using System.Collections; using UnityEngine; namespace AibisDream.MiniGame.HuoShan { /// /// SaleView 进入动画控制器 /// 负责在进入销售系统时播放进入动画,包括: /// 1. 轨道底座组伸张 /// 2. 内环和外边框放大 /// 3. 滑片从缩着变为伸出(帧动画 c→b→a) /// 4. 夹片淡入 /// /// Animator 预期配置: /// - Idle 状态:使用进入动画同一 clip,Speed=0,保持缩起 pose(第一帧),不播放 /// - EnterStepMode 状态:播放 clip,播完后由代码禁用 Animator,维持最后一帧,释放控制权 /// [RequireComponent(typeof(Animator))] public class SaleViewEnterAnimation : MonoBehaviour { private const string AnimParamTriggerEnter = "Enter"; private const string AnimStateNameEnter = "EnterStepMode"; // 与 EnterStepMode.controller 中状态名一致 [Header("Animator 配置")] [Tooltip("Animator Controller(带 Idle/Enter 两个状态)")] [SerializeField] private RuntimeAnimatorController animatorController; [Tooltip("进入动画 Clip(与 Controller 中 EnterStepMode 状态使用同一 clip),用于播完后烘焙最后一帧")] [SerializeField] private AnimationClip enterClip; private Animator _animator; private int _triggerEnterId; private void Awake() { _animator = GetComponent(); if (animatorController != null) _animator.runtimeAnimatorController = animatorController; _triggerEnterId = Animator.StringToHash(AnimParamTriggerEnter); } private void OnEnable() { // 确保初始状态为 Idle(缩起) _animator.Rebind(); _animator.Update(0f); } /// /// 播放进入动画(进入销售系统时调用) /// public void PlayEnterAnimation() { if (_animator == null || !_animator.enabled) return; _animator.SetTrigger(_triggerEnterId); } /// /// 播放进入动画,并在播放完成后释放控制权(禁用 Animator), /// 以便 SliderController 等代码控制轨道、滑片等物件,避免 Animator 持续覆盖。 /// public IEnumerator PlayEnterAnimationAndReleaseWhenDone() { PlayEnterAnimation(); if (_animator == null || !_animator.enabled) yield break; // 等待过渡到 EnterStepMode 状态 yield return null; var stateInfo = _animator.GetCurrentAnimatorStateInfo(0); while (!stateInfo.IsName(AnimStateNameEnter)) { yield return null; stateInfo = _animator.GetCurrentAnimatorStateInfo(0); } // 等待 EnterStepMode 播放完成(normalizedTime >= 1) while (stateInfo.normalizedTime < 1f) { yield return null; stateInfo = _animator.GetCurrentAnimatorStateInfo(0); } // 烘焙最后一帧到 transform,否则禁用 Animator 会回退到默认 pose if (enterClip != null) { enterClip.SampleAnimation(_animator.gameObject, enterClip.length); } else { Debug.LogWarning("[SaleViewEnterAnimation] enterClip 未赋值,禁用 Animator 后可能出现回退,请在 Inspector 中指定 EnterStepMode.anim", this); } _animator.enabled = false; } /// /// 释放动画控制权(禁用 Animator),让代码可以接管动画控制的物件。 /// public void ReleaseControl() { if (_animator != null) _animator.enabled = false; } /// /// 重置到初始状态(可用于关闭时重置)。会重新启用 Animator 以便下次进入时能播放动画。 /// public void ResetToIdle() { if (_animator == null) return; _animator.enabled = true; _animator.Rebind(); _animator.Update(0f); } } }