Как синхронизировать несколько аниматоров?
| |
Jlexa123 | Дата: Четверг, 08 Апреля 2021, 10:23 | Сообщение # 1 |
частый гость
Сейчас нет на сайте
| Всем привет, давно я тут не писал я по прежнему нуб, но теперь я делаю свою игру и вот такой вопрос теперь: Как синхронизировать несколько аниматоров, чтобы анимация в них запускалась одновременно?
Все это нужно для кастомизации, я не знаю как правильно ее делать, по этому делаю вот так: есть персонаж с покадровой анимацией, у него порядка 12 дочерних объектов со спрайт рендерами и аниматорами которые играют роль сапог, мечей и.т.д есть главный управляющий скрипт, в котором прописано передвижение перса, атаки и.т.д и маленький фикс скрипт, который берет параметры вроде скорости передвижения и состояния(на земле или в воздухе) и управляет аниматором, такая система позволяет запускать все аниматоры одинаково, они проигрывают анимацию одинаково даже при лагах (проверено на трех разных по мощности компах), однако стоит снять предмет и надеть его снова, как происходит рассинхронизация и аниматоры воспроизводят анимацию по разному.
код в скрипте управления анимацией:
public class PItemFix : MonoBehaviour { public PlayerMoove player; private Animator anim; private bool pause = false; определяет паузу непосредственно в этом скрипте public int identificator; - для тестирования параметров в конкретном аниматоре
private void Start() { this.anim = this.GetComponent<Animator>(); }
private void Update() { if (MainController.getPauseStatus() && !this.pause) main тру ля ля контроллер - ставит всю игру на паузу { this.anim.StartPlayback(); - останавливаем все анимации this.anim.PlayInFixedTime("Stay 2", 0, 0); - меняем позу (для всех объектов) для смены предмета this.pause = true; } else if (!MainController.getPauseStatus() && this.pause) { this.anim.PlayInFixedTime("Stay 2", 0, 0); - дополнительно синхронизируем аниматоры this.anim.StopPlayback(); - запускаем все аниматоры this.pause = false; - убираем паузу в этом скрипте }
каждый кадр обновляем параметры для всех аниматоров
this.anim.SetBool("Ground", this.player.GROund); this.anim.SetFloat("Speed", Mathf.Abs(this.player.HORinput)); this.anim.SetBool("Jump", this.player.JUMps); this.anim.SetBool("Attack", this.player.ATTack); this.anim.SetFloat("Duration", Mathf.Sign(this.player.HORinput)); } -------------------------------------------------------------------------
this.anim.PlayInFixedTime("Stay 2", 0, 0); this.anim.StopPlayback();
Почему-то даже когда аниматоры синхронизированы, запускаются они все равно по разному, и в итоге одежда двигается отдельно от персонажа, при этом только та часть одежды, которая была выключена через gameObject.SetActive(false); Как правильно синхронизировать аниматоры? Слои в аниматор контроллере мне похоже не подойдут, потому что нужно делать 500 слоев для каждой комбинации одежды. (+ не знаю как работать со слоями).
Там есть такая фишка, что когда объект деактивируется через gameObject.SetActive(False), а потом активируется, то аниматор начинает проигрывать анимацию, по этому его нужно остановить и и выставить конкретную позицию, но после этого он все равно запускается не одновременно с другими аниматорами.
Сообщение отредактировал Jlexa123 - Четверг, 08 Апреля 2021, 10:46 |
|
| |
drcrack | Дата: Четверг, 08 Апреля 2021, 13:43 | Сообщение # 2 |
старожил
Сейчас нет на сайте
| при включении обьекта нужно запросить состояние главного аниматора через GetCurrentAnimatorStateInfo и запустить анимацию с нужного места с помощью Play у которой есть параметр normalizedTime
|
|
| |
Jlexa123 | Дата: Понедельник, 12 Апреля 2021, 10:48 | Сообщение # 3 |
частый гость
Сейчас нет на сайте
| Наконец-то удалось опробовать Ваш совет, но что-то у меня не очень получилось, пробовал запросить состояние через GetCurrentAnimatorStateInfo(0).normalizedTime у аниматора с анимацией тела, затем запускать через anim.Play("Stay 2", 0, переменная с normalizedTime), но Play() но по моему вообще не какого эффекта не дает. Так же удалось узнать, что изначально normalizedTime везде разный, однако анимации экипировки работают синхронно, как только ставлю игру на паузу, normalizedTime везде становится одинаковым, после того как выключаю паузу, он опять становится разным, но анимация работает синхронно, стоит отключить объект с предметом экипировки, как анимация экипировки начинает работать не синхронно с персонажем, а normalizedTime все так же одинаковый во время паузы и разный без паузы. Можете написать поконкретней, как это сделать?
ссылка на тестовую сценку https://disk.yandex.ru/d/FQ_5hv6R65lPuA A\D - движение влево вправо, P - пауза, E - во время паузы снять \ одеть штаны
Сообщение отредактировал Jlexa123 - Понедельник, 12 Апреля 2021, 12:26 |
|
| |
drcrack | Дата: Понедельник, 12 Апреля 2021, 23:19 | Сообщение # 4 |
старожил
Сейчас нет на сайте
| попробуй Play(0, 0, переменная с normalizedTime) это должно перемотать активный клип
|
|
| |
Jlexa123 | Дата: Среда, 14 Апреля 2021, 12:53 | Сообщение # 5 |
частый гость
Сейчас нет на сайте
| Не помогло, клип перематывается и игнорируя параметр "ground" переходит на другую анимацию, затем мгновенно переходит обратно. Однако все как-то само собой решилось, если выключить персонажа целиком, а затем включить через gameObject.SetActive() то после синхронизации через PlayInFixedTime("Stay 2", 0, 0) и запуска всех аниматоров через StopPlayback() все начинает работать как надо, даже если потом отключать и включать любые части одежды. ________________________________________________________________________________________________________ Не знаю, кто как делает подобную кастомизацию, но лично у меня с добавлением функции перетаскивания предмета в слот для одежды на персонаже в инвентаре, данная фишка работать перестала, опять одежда стала "бегать" отдельно от персонажа, пока решилось все тем же отключением персонажа, но после каждой смены предмета экипировки.Добавлено (26 Ноября 2022, 15:33) --------------------------------------------- Вот прошла уже целая куча времени, я успел, к сожалению совсем чуть-чуть поработать на очень крупную компанию, и по этому выкладываю мини гайд для новичков, как сделать кастомизацию с покадровой анимацией без этой хрени с синхронизацией аниматоров.
Нужно в объект с персонажем добавить все вещи которые есть, например body/armor/ gold armor, glass armor и.т.д. Затем создать анимацию, например idle и запихнуть туда все спрайты анимации idle для всех видов armor. Менять доспехи путем отключения объекта у персонажа, например отключаем glass armor, включаем gold armor. Минусы: - куча предметов на персонаже - очень объемная анимация (100 штанов - 100 строк со свойствами в анимационном клипе )
Плюсы: - Всего одна анимация, для каждой категории (armor, pants и.т.д) в которой собраны все однотипные предметы.
Есть способ с разделением на слои, каждый слой в аниматоре - отдельный предмет, но он мне пока кажется более геморным, так как для каждого предмета нужно будет делать свою анимацию idle и.т.д, переключаем предметы так же, через отключение объекта на персонаже, а вот как отключить слой в аниматоре не понятно, либо они все время будут проигрываться (слои синхронизированы со слоем, с болванкой для персонажа).
Сообщение отредактировал Jlexa123 - Понедельник, 24 Мая 2021, 09:38 |
|
| |
|