116 lines
4.3 KiB
C#
116 lines
4.3 KiB
C#
using System.Collections;
|
||
using UnityEngine;
|
||
|
||
namespace AibisDream.MiniGame.HuoShan
|
||
{
|
||
/// <summary>
|
||
/// SaleView 进入动画控制器
|
||
/// 负责在进入销售系统时播放进入动画,包括:
|
||
/// 1. 轨道底座组伸张
|
||
/// 2. 内环和外边框放大
|
||
/// 3. 滑片从缩着变为伸出(帧动画 c→b→a)
|
||
/// 4. 夹片淡入
|
||
///
|
||
/// Animator 预期配置:
|
||
/// - Idle 状态:使用进入动画同一 clip,Speed=0,保持缩起 pose(第一帧),不播放
|
||
/// - EnterStepMode 状态:播放 clip,播完后由代码禁用 Animator,维持最后一帧,释放控制权
|
||
/// </summary>
|
||
[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<Animator>();
|
||
if (animatorController != null)
|
||
_animator.runtimeAnimatorController = animatorController;
|
||
_triggerEnterId = Animator.StringToHash(AnimParamTriggerEnter);
|
||
}
|
||
|
||
private void OnEnable()
|
||
{
|
||
// 确保初始状态为 Idle(缩起)
|
||
_animator.Rebind();
|
||
_animator.Update(0f);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 播放进入动画(进入销售系统时调用)
|
||
/// </summary>
|
||
public void PlayEnterAnimation()
|
||
{
|
||
if (_animator == null || !_animator.enabled) return;
|
||
_animator.SetTrigger(_triggerEnterId);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 播放进入动画,并在播放完成后释放控制权(禁用 Animator),
|
||
/// 以便 SliderController 等代码控制轨道、滑片等物件,避免 Animator 持续覆盖。
|
||
/// </summary>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 释放动画控制权(禁用 Animator),让代码可以接管动画控制的物件。
|
||
/// </summary>
|
||
public void ReleaseControl()
|
||
{
|
||
if (_animator != null) _animator.enabled = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 重置到初始状态(可用于关闭时重置)。会重新启用 Animator 以便下次进入时能播放动画。
|
||
/// </summary>
|
||
public void ResetToIdle()
|
||
{
|
||
if (_animator == null) return;
|
||
_animator.enabled = true;
|
||
_animator.Rebind();
|
||
_animator.Update(0f);
|
||
}
|
||
}
|
||
}
|