BaseHacks
Вы находитесь: Wc3Player.ru » Как проиграть анимации типа Stand 2, Spell-4 - Форум
  • Страница 1 из 1
  • 1
Как проиграть анимации типа Stand 2, Spell-4
WESTKILLERДата: Пятница, 12.03.2010, 20:13 | Сообщение # 1
]Pro PerSoN ShahNazaR[
Группа: Пользователи
Сообщений: 712
Награды: 36
Репутация: 5475
Замечания: 0%
Статус: Offline
Статья доступно обьясняет как проигрывать конкретные анимации из списка анимаций юнита, к примеру анимации с номерами типа Stand - 2 или анимации с тегами типа Spell Alternate. В кинематиках для придания большей реалистичности действию часто используется триггерная команда
Анимация - Play unit animation.
Например, если какой-то герой по сюжету должен прыгать от радости, а он вместо этого стоит неподвижно, получится как-то неестественно. Самый лучший выход в этом случае - проиграть анимацию прыжка. Например, у Лорда Ужаса (Дридлорда) прыжок - это анимация Stand-3. И вот тут-то как раз и возникает проблема. Оказывается, что команда проигрывания анимации работает сразу с группой анимаций. Т.е. при попытке проиграть не Stand, а Stand 2, Stand 3 или Stand 4 результат будет непредсказуемый. Скорее всего, проиграется обычная анимация Stand (она же - Stand 1) или же вообще ничего не проиграется.
В случае с лордом ужаса проблема вполне разрешима - достаточно использовать для кинематики Вариматаса - у него есть анимация прыжка Spell Third, которая проигрывается без проблем.
Но в любом случае, очень обидно, что большинство анимаций юнитов оказываются триггерно недоступными. Особенно обидно бывает, когда импортируешь в карту модель WoW 10Мб весом, а потом оказывается, что из всех тамошних анимаций можно использовать лишь 3-4 штуки. Остальное же - просто мёртвый груз, ибо War вообще не понимает анимации с нестандартными именами (навроде Attack Very-Very Hard).

Триггерно решить эту проблему невозможно. А вот у JASS'еров есть шансы. Думаю, многие любители JASS во время просмотра common.j обращали своё внимание на функцию

Code

native SetUnitAnimationByIndex takes unit whichUnit, integer whichAnimation returns nothing

Судя по её названию, она должна проигрывать анимацию не по имени, а по номеру. Т.е. всё, что надо сделать, это подставить туда номер анимации - и готово, имя не имеет значения!
Эх, если бы всё и впрямь было так просто :(. Blizzard'ы не были бы Blizzard'ами, если бы не придумали очередной способ сверления зубов дракона через задний проход. Т.е. данная функция попросту не работает! Причём абсолютно, все её вызовы просто игнорируются и на анимацию никак не влияют.

Так как же всё-таки проиграть нужную анимацию юнита?
Первое, что для этого нужно сделать - создать анимационный тег. Это особый объект, представляющий собой всего лишь список всех анимаций юнита. Создаётся он при помощи ещё одной "загадочной" JASS-функции:

Code

native AddUnitAnimationProperties  takes unit whichUnit, string animProperties,  
                    boolean add returns nothing

Что только о ней не пишут во всяких мануалах! По одной версии, она добавляет новые имена анимаций; по другой - новые анимационные свойства (что бы это значило). В JASSWiki данная функция "поясняется" так: "Добавляет/удаляет анимационные свойства юнита".
На самом же деле она всего лишь создаёт анимационный тег (список анимаций юнита) и "цепляет" его на указанный юнит. Рассмотрим параметры этой функции:
whichUnit - всего-навсего тот юнит, анимационный тег которого мы хотим создать (или удалить, т.к. эта же функция способна и удалять анимационные теги).
animProperties - имя анимационного тега. Может быть любым. Используется для дальнейших ссылок на анимационный тег. Если ссылки на тег в дальнейшем не понадобятся, то в этом параметре можно передать null. Тогда ссылка на тег теряется и происходит утечка памяти (всем участникам команды DotaTeam рекомендуется всегда передавать сюда null).
add - если сюда передать true, то тег создаётся; если false - удаляется (при условии, конечно, что на юните есть тег с указанным именем). Все, кто озабочен утечками, должны непременно удалять теги, когда они становятся ненужными. Все остальные могут упростить себе жизнь и оставить теги неудалёнными (благо в любой кинематике и без того утечек масса).
Кстати, триггерщики для создания тега могут воспользоваться командой
Анимация - Add/Remove unit animation tag. Вообще говоря, это очень странно: создать тег триггеры позволяют, а работать с ним - нет :).

Итак, тег создан (для тех, кто забыл - напоминаю: тег есть список всех анимаций юнита). А вот теперь смело вызываем SetUnitAnimationByIndex. Триггерщики могут воспользоваться для этого Custom script:

Code
call SetUnitAnimationByIndex(gg_unit_hfoo_0002,3)

Первый параметр этой функции - юнит, анимацию которого нужно проиграть. Второй - номер анимации (нумерация идёт с нуля, 0 - это, как правило, Stand 1).
Триггерщикам будет несколько сложновато определять, что нужно написать в качестве юнита :), выглядит это действительно страшновато. Ну что ж, могу посоветовать создать какой-нибудь триггер для тестирования, содержащий всего 1 команду, использующую данный юнит. Затем конвертировать триггер в текст и глянуть имя глобалки юнита. (Надеюсь, я вас ещё не загрузил?)
Вторая проблема - определить номер нужной анимации. WE тут ничем не поможет, т.к. его окошко анимаций сортирует их по алфавиту, а не по номеру. Номер можно определить, открыв файл модели юнита в блокноте (лучше - в виде MDL), War3Viewer, MdlVis, W3ME или подобной программе. После чего просто подсчитать анимации (от нуля), пока не дойдёте до нужной.

Итак, ещё раз (кратко, для триггерщиков):
1. Анимация - Add/Remove unit animation tag. Создаётся список анимаций на юните. Достаточно создать тег один раз, и можно проигрывать сколько угодно анимаций для этого юнита.
2. Custom script: call SetUnitAnimationByIndex(gg_unit_XXXX_YYYY,N) предварительно определив имя глобалки, содержащей юнит и номер желаемой анимации.

Ну, вроде и всё. Если что-то будет непонятно - пишите. До скорых встреч :end:

Дополнение - загрузка игры

Здравствуйте, с вами ScorpioT1000 smile

Появилась новая проблема - сбивание анимации, применённой с помощью "SetUnitAnimationByIndex" функцией "SetUnitPosition".

Возникает она после того, как игрок загрузит сохранённую ранее игру на вашей карте.

Решение "простое" - пересоздаём этого юнита.

Подробнее:
1. Отключаем все наши системы, "затрагивающие" нашего юнита.
2. Отключаем все триггеры, реагирующие на событие смерти нашего юнита (для этого просто надо иметь переменную типа bool в условиях и применять её где надо).
3. заменяем нашего юнита на того-же, например:

Code
my_unit_var = ReplaceUnitBJ(my_unit_var, MY_UNIT_ID, bj_UNIT_STATE_METHOD_ABSOLUTE)
 
mega4elДата: Воскресенье, 03.10.2010, 02:54 | Сообщение # 2
Начинающий растаман
Группа: Пользователи
Сообщений: 15
Награды: 0
Репутация: 0
Замечания: 20%
Статус: Offline
интересная статья
 
  • Страница 1 из 1
  • 1
Поиск: