feat(scene-mgmt): 添加随机动画播放系统和 Yarn 指令
This commit is contained in:
@@ -9,6 +9,7 @@ namespace AibisDream
|
||||
public class AnimatorCenter : SingletonBase<AnimatorCenter>
|
||||
{
|
||||
private readonly Dictionary<string, AnimatorHandler> _handlers = new();
|
||||
private readonly Dictionary<string, RandomAnimatorHandler> _randomHandlers = new();
|
||||
|
||||
private AnimatorCenter() { }
|
||||
|
||||
@@ -22,6 +23,42 @@ namespace AibisDream
|
||||
_handlers.Remove(handler.animatorName);
|
||||
}
|
||||
|
||||
public void RegisterRandomHandler(RandomAnimatorHandler handler)
|
||||
{
|
||||
_randomHandlers.Add(handler.handelrName, handler);
|
||||
}
|
||||
|
||||
public void UnregisterRandomHandler(RandomAnimatorHandler handler)
|
||||
{
|
||||
_randomHandlers.Remove(handler.handelrName);
|
||||
}
|
||||
|
||||
public void StartRandomAnimation(string handlerName)
|
||||
{
|
||||
if (!TryGetRandomHandler(handlerName, out RandomAnimatorHandler randomHandler))
|
||||
return;
|
||||
|
||||
randomHandler.StartRandomPlay();
|
||||
}
|
||||
|
||||
public void StopRandomAnimation(string handlerName)
|
||||
{
|
||||
if (!TryGetRandomHandler(handlerName, out RandomAnimatorHandler randomHandler))
|
||||
return;
|
||||
|
||||
randomHandler.StopRandomPlay();
|
||||
}
|
||||
|
||||
private bool TryGetRandomHandler(string handlerName, out RandomAnimatorHandler handler)
|
||||
{
|
||||
if (_randomHandlers.TryGetValue(handlerName, out handler))
|
||||
return true;
|
||||
|
||||
Debug.LogError($"AnimatorCenter: 未找到名为 \"{handlerName}\" 的 RandomAnimatorHandler。");
|
||||
handler = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetHandler(string animatorName, out AnimatorHandler handler)
|
||||
{
|
||||
if (_handlers.TryGetValue(animatorName, out handler))
|
||||
@@ -102,6 +139,14 @@ namespace AibisDream
|
||||
animatorHandler.Reset();
|
||||
}
|
||||
|
||||
public void ReturnToDefaultState(string animatorName)
|
||||
{
|
||||
if (!TryGetHandler(animatorName, out AnimatorHandler animatorHandler))
|
||||
return;
|
||||
|
||||
animatorHandler.ReturnToDefaultState();
|
||||
}
|
||||
|
||||
public void HideAnimation(string animatorName)
|
||||
{
|
||||
if (!TryGetHandler(animatorName, out AnimatorHandler animatorHandler))
|
||||
|
||||
@@ -347,6 +347,24 @@ namespace AibisDream
|
||||
ReleaseAddressableHandle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将 Animator 状态机恢复到当前 <see cref="RuntimeAnimatorController"/> 的默认入口状态(参数与层会按控制器重置),
|
||||
/// 不释放 Addressable、不还原已替换的运行时控制器。用于在保留当前加载的控制器前提下清掉过渡与参数。
|
||||
/// </summary>
|
||||
public void ReturnToDefaultState()
|
||||
{
|
||||
if (!EnsureAnimator())
|
||||
return;
|
||||
|
||||
CancelCompletionCoroutine();
|
||||
_onCompleteCallback = null;
|
||||
|
||||
EnsurePlayingSpeedForNewClip();
|
||||
|
||||
animator.Rebind();
|
||||
animator.Update(0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前层当前状态下,已播放时长(秒)。过渡或非目标状态时语义以当前 StateInfo 为准。
|
||||
/// </summary>
|
||||
|
||||
@@ -30,5 +30,17 @@ namespace AibisDream
|
||||
{
|
||||
AnimatorCenter.Instance.HideAnimation(animatorName);
|
||||
}
|
||||
|
||||
[YarnCommand("start_random_animation")]
|
||||
public static void StartRandomAnimation(string handlerName)
|
||||
{
|
||||
AnimatorCenter.Instance.StartRandomAnimation(handlerName);
|
||||
}
|
||||
|
||||
[YarnCommand("stop_random_animation")]
|
||||
public static void StopRandomAnimation(string handlerName)
|
||||
{
|
||||
AnimatorCenter.Instance.StopRandomAnimation(handlerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AibisDream
|
||||
{
|
||||
public class RandomAnimatorHandler : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Animator targetAnimator;
|
||||
public string handelrName;
|
||||
[SerializeField] private Vector2 randomDurationRange;
|
||||
[SerializeField] private int randomCount;
|
||||
[SerializeField] private bool playOnAwake;
|
||||
|
||||
private bool _isPlaying;
|
||||
private float _curduration;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (playOnAwake)
|
||||
{
|
||||
StartRandomPlay();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
AnimatorCenter.Instance.RegisterRandomHandler(this);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
AnimatorCenter.Instance.UnregisterRandomHandler(this);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_isPlaying)
|
||||
{
|
||||
_curduration -= Time.deltaTime;
|
||||
if (_curduration <= 0)
|
||||
{
|
||||
RandomPlay();
|
||||
_curduration = RandomDuration();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RandomPlay()
|
||||
{
|
||||
targetAnimator.ResetTrigger("RandomPlay");
|
||||
|
||||
// 设置参数
|
||||
var index = RandomIndex();
|
||||
targetAnimator.SetInteger("RandomIndex", index);
|
||||
// 播放
|
||||
targetAnimator.SetTrigger("RandomPlay");
|
||||
|
||||
}
|
||||
|
||||
public void StartRandomPlay()
|
||||
{
|
||||
_isPlaying = true;
|
||||
_curduration = RandomDuration();
|
||||
}
|
||||
|
||||
public void StopRandomPlay()
|
||||
{
|
||||
_isPlaying = false;
|
||||
}
|
||||
|
||||
private float RandomDuration()
|
||||
{
|
||||
return Random.Range(randomDurationRange.x, randomDurationRange.y);
|
||||
}
|
||||
|
||||
private int RandomIndex()
|
||||
{
|
||||
return Random.Range(0, randomCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d2070ae592dcf94a98db28bc06281c2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user