From 487ee0a991f52139cecb6ca1d6807b20a20eae00 Mon Sep 17 00:00:00 2001 From: Ding Yuntian <1491671119@qq.com> Date: Tue, 21 Apr 2026 14:10:44 +0800 Subject: [PATCH] =?UTF-8?q?feat(scene-mgmt):=20=E6=B7=BB=E5=8A=A0=E9=9A=8F?= =?UTF-8?q?=E6=9C=BA=E5=8A=A8=E7=94=BB=E6=92=AD=E6=94=BE=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E5=92=8C=20Yarn=20=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AnimatorKit/AnimatorCenter.cs | 45 +++++++++++ .../AnimatorKit/AnimatorHandler.cs | 18 +++++ .../AnimatorKit/AnimatorYarnCommand.cs | 12 +++ .../AnimatorKit/RandomAnimatorHandler.cs | 80 +++++++++++++++++++ .../AnimatorKit/RandomAnimatorHandler.cs.meta | 11 +++ 5 files changed, 166 insertions(+) create mode 100644 Assets/Scripts/SceneManagement/AnimatorKit/RandomAnimatorHandler.cs create mode 100644 Assets/Scripts/SceneManagement/AnimatorKit/RandomAnimatorHandler.cs.meta diff --git a/Assets/Scripts/SceneManagement/AnimatorKit/AnimatorCenter.cs b/Assets/Scripts/SceneManagement/AnimatorKit/AnimatorCenter.cs index e4eea2705..6e7c36aa3 100644 --- a/Assets/Scripts/SceneManagement/AnimatorKit/AnimatorCenter.cs +++ b/Assets/Scripts/SceneManagement/AnimatorKit/AnimatorCenter.cs @@ -9,6 +9,7 @@ namespace AibisDream public class AnimatorCenter : SingletonBase { private readonly Dictionary _handlers = new(); + private readonly Dictionary _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)) diff --git a/Assets/Scripts/SceneManagement/AnimatorKit/AnimatorHandler.cs b/Assets/Scripts/SceneManagement/AnimatorKit/AnimatorHandler.cs index 31afe7372..0a4feb1be 100644 --- a/Assets/Scripts/SceneManagement/AnimatorKit/AnimatorHandler.cs +++ b/Assets/Scripts/SceneManagement/AnimatorKit/AnimatorHandler.cs @@ -347,6 +347,24 @@ namespace AibisDream ReleaseAddressableHandle(); } + /// + /// 将 Animator 状态机恢复到当前 的默认入口状态(参数与层会按控制器重置), + /// 不释放 Addressable、不还原已替换的运行时控制器。用于在保留当前加载的控制器前提下清掉过渡与参数。 + /// + public void ReturnToDefaultState() + { + if (!EnsureAnimator()) + return; + + CancelCompletionCoroutine(); + _onCompleteCallback = null; + + EnsurePlayingSpeedForNewClip(); + + animator.Rebind(); + animator.Update(0f); + } + /// /// 当前层当前状态下,已播放时长(秒)。过渡或非目标状态时语义以当前 StateInfo 为准。 /// diff --git a/Assets/Scripts/SceneManagement/AnimatorKit/AnimatorYarnCommand.cs b/Assets/Scripts/SceneManagement/AnimatorKit/AnimatorYarnCommand.cs index 0a5c03c39..e03b73022 100644 --- a/Assets/Scripts/SceneManagement/AnimatorKit/AnimatorYarnCommand.cs +++ b/Assets/Scripts/SceneManagement/AnimatorKit/AnimatorYarnCommand.cs @@ -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); + } } } diff --git a/Assets/Scripts/SceneManagement/AnimatorKit/RandomAnimatorHandler.cs b/Assets/Scripts/SceneManagement/AnimatorKit/RandomAnimatorHandler.cs new file mode 100644 index 000000000..4769b7b7d --- /dev/null +++ b/Assets/Scripts/SceneManagement/AnimatorKit/RandomAnimatorHandler.cs @@ -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); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/SceneManagement/AnimatorKit/RandomAnimatorHandler.cs.meta b/Assets/Scripts/SceneManagement/AnimatorKit/RandomAnimatorHandler.cs.meta new file mode 100644 index 000000000..04e3dbeaf --- /dev/null +++ b/Assets/Scripts/SceneManagement/AnimatorKit/RandomAnimatorHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d2070ae592dcf94a98db28bc06281c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: