Files
aibis-dream/Assets/Scripts/MiniGame/HuoShan/SalesSystem/SaleViewEnterAnimation.cs
T

116 lines
4.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}
}