Из-за чего анимация не проигрывается при включении объекта?
Ссылка скопирована
Сейчас ситуация такая: суть проблемы: при использовании метода HideItemsInHand внутри ShowItemInHand() ломается аниматор и анимация застывает на 1 кадре
Скрипт:
using UnityEngine; using UnityEngine.UI; public class QuickslotInventory : MonoBehaviour { // Объект у которого дети являются слотами [SerializeField] private Transform quickslotParent; [SerializeField] private Transform _itemHolder; [SerializeField] private InventoryManager inventoryManager; public int currentQuickslotID = 0; [SerializeField] private Sprite selectedSprite; [SerializeField] private Sprite notSelectedSprite; [SerializeField] private MenuPaused _menuManager; [SerializeField] private InventorySlot _activeSlot; // Update is called once per frame void Update() { float mw = Input.GetAxis("Mouse ScrollWheel"); // Используем колесико мышки if (mw < 0.1 && _menuManager.isMenuPaused == false && quickslotParent.childCount < 5) { // Берем предыдущий слот и меняем его картинку на обычную quickslotParent.GetChild(currentQuickslotID).GetComponent<Image>().sprite = notSelectedSprite; // Если крутим колесиком мышки вперед и наше число currentQuickslotID равно последнему слоту, то выбираем наш первый слот (первый слот считается нулевым) if (currentQuickslotID >= quickslotParent.childCount-1) { currentQuickslotID = 0; } else { // Прибавляем к числу currentQuickslotID единичку currentQuickslotID++; } // Берем предыдущий слот и меняем его картинку на "выбранную" quickslotParent.GetChild(currentQuickslotID).GetComponent<Image>().sprite = selectedSprite; _activeSlot = quickslotParent.GetChild(currentQuickslotID).GetComponent<InventorySlot>(); ShowItemInHand(); // Что то делаем с предметом: } if (mw > -0.1 && _menuManager.isMenuPaused == false && quickslotParent.childCount < 5) { // Берем предыдущий слот и меняем его картинку на обычную quickslotParent.GetChild(currentQuickslotID).GetComponent<Image>().sprite = notSelectedSprite; // Если крутим колесиком мышки назад и наше число currentQuickslotID равно 0, то выбираем наш последний слот if (currentQuickslotID <= 0) { currentQuickslotID = quickslotParent.childCount-1; } else { // Уменьшаем число currentQuickslotID на 1 currentQuickslotID--; } // Берем предыдущий слот и меняем его картинку на "выбранную" quickslotParent.GetChild(currentQuickslotID).GetComponent<Image>().sprite = selectedSprite; _activeSlot = quickslotParent.GetChild(currentQuickslotID).GetComponent<InventorySlot>(); ShowItemInHand(); // Что то делаем с предметом: } // Используем цифры for(int i = 0; i < quickslotParent.childCount; i++) { // если мы нажимаем на клавиши 1 по 5 то... if (Input.GetKeyDown((i + 1).ToString()) && _menuManager.isMenuPaused == false && quickslotParent.childCount < 5) { // проверяем если наш выбранный слот равен слоту который у нас уже выбран, то if (currentQuickslotID == i) { // Ставим картинку "selected" на слот если он "not selected" или наоборот if (quickslotParent.GetChild(currentQuickslotID).GetComponent<Image>().sprite == notSelectedSprite) { quickslotParent.GetChild(currentQuickslotID).GetComponent<Image>().sprite = selectedSprite; _activeSlot = quickslotParent.GetChild(currentQuickslotID).GetComponent<InventorySlot>(); ShowItemInHand(); } else { quickslotParent.GetChild(currentQuickslotID).GetComponent<Image>().sprite = notSelectedSprite; _activeSlot = null; HideItemsInHand(); } } // Иначе мы убираем свечение с предыдущего слота и светим слот который мы выбираем else { quickslotParent.GetChild(currentQuickslotID).GetComponent<Image>().sprite = notSelectedSprite; currentQuickslotID = i; quickslotParent.GetChild(currentQuickslotID).GetComponent<Image>().sprite = selectedSprite; _activeSlot = quickslotParent.GetChild(currentQuickslotID).GetComponent<InventorySlot>(); ShowItemInHand(); } } } } private void ShowItemInHand() { if (_activeSlot.item == null) { return; } for (int i = 0; i < _itemHolder.childCount; i++) { if (_activeSlot.item.itemName == _itemHolder.GetChild(i).name) { _itemHolder.GetChild(i).gameObject.SetActive(true); } } } private void HideItemsInHand() { for (int i = 0; i < _itemHolder.childCount; i++) { _itemHolder.GetChild(i).gameObject.SetActive(false); } } }
Частично помогло_animator.keepAnimatorStateOnDisable = true;Сейчас ситуация такая:, но при дефолтно значении, то есть false в аниматоре следующая картина: анимации застывают на 1 кадре и не могут проиграться дальше
Нужно решить такую задачу?
Заказать помощь
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Лучший ответ
1
Другие ответы (0)
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопроскомментарий
Вам также может быть интересно
VPN
Как правильно настроить vless для Android TV?
1 ответ
Pyrogram
Как правильно зарегистрировать юзер бота в Telegram?
1 ответ
печатные-платы
Как заставить запускаться программу M3.exe от компании Hanxing AOI в инспекционной машине на Windows 7 Pro?
1 ответ
Linux
Как диагностировать зависание RK3568 U-boot на Starting kernel?
1 ответ


По описанию очень похоже, что HideItemsInHand() отключает объект, на котором висит Animator, или отключает дочерний объект в момент, когда вы сразу пытаетесь запустить анимацию. В Unity при SetActive(false) состояние Animator сбрасывается/останавливается, а при повторном включении он может остаться на первом кадре, если триггер был выставлен до активации или если объект включили не в том порядке.
Типичная ошибка в инвентарях такая: сначала скрываются все предметы в руке, потом включается нужный предмет, но Animator/Animation на нем уже получил Play/SetTrigger в момент, когда GameObject был inactive. Визуально это выглядит как “анимация застывает на первом кадре”.
Проверьте порядок действий. Надежная схема:
private void ShowItemInHand(GameObject item) { HideItemsInHand(); item.SetActive(true); var animator = item.GetComponentInChildren<Animator>(true); if (animator != null) { animator.Rebind(); animator.Update(0f); animator.Play("Show", 0, 0f); } }
Если Animator находится на общем _itemHolder, а вы выключаете только модели предметов, лучше не отключать объект с Animator. Оставьте holder активным, а скрывайте MeshRenderer/SpriteRenderer или конкретные child-модели. Это стабильнее, чем каждый раз выключать всю иерархию.
Еще один частый момент: если в Animator Controller переход из Entry в состояние зависит от trigger, а trigger вызывается на inactive-объекте, он может не отработать. Тогда вместо SetTrigger попробуйте прямой Play с нулевой нормализованной позицией, как в примере выше.
Также проверьте галочку Animator: Keep Animator Controller State On Disable. Она может помочь, если вам нужно сохранять состояние при выключении объекта, но для предмета в руке чаще правильнее явно переинициализировать анимацию после включения. В вашем случае я бы сначала убедился, что HideItemsInHand() не выключает _itemHolder или родителя активного слота, а затем перенес запуск анимации строго после item.SetActive(true).