using System; using System.Collections.Generic; using UnityEngine; using Cysharp.Threading.Tasks; /// /// US3: 异步资源守卫,延迟特效/Spine播放直到资源就绪。 /// 在资源未加载完成时排队播放请求,加载完成后按顺序执行。 /// public class AsyncResourceGuard { private bool _isReady; private readonly Queue _pendingActions = new Queue(); private UniTaskCompletionSource _readySource; public bool IsReady => _isReady; public AsyncResourceGuard() { _isReady = false; _readySource = new UniTaskCompletionSource(); } /// /// 标记资源已就绪,执行所有排队的动作。 /// public void SetReady() { if (_isReady) return; _isReady = true; _readySource.TrySetResult(); // 执行所有排队的动作 while (_pendingActions.Count > 0) { var action = _pendingActions.Dequeue(); try { action?.Invoke(); } catch (Exception e) { Debug.LogException(e); } } } /// /// 排队一个动作:如果资源已就绪则立即执行,否则排队等待。 /// public void EnqueueOrExecute(Action action) { if (action == null) return; if (_isReady) { action.Invoke(); } else { _pendingActions.Enqueue(action); } } /// /// 等待资源就绪(可用于 await)。 /// public UniTask WaitUntilReady() { if (_isReady) return UniTask.CompletedTask; return _readySource.Task; } /// /// 重置状态,用于资源重新加载。 /// public void Reset() { _isReady = false; _pendingActions.Clear(); _readySource = new UniTaskCompletionSource(); } /// /// 清空所有排队的动作(如场景切换时)。 /// public void ClearPending() { _pendingActions.Clear(); } } /// /// US3: MonoBehaviour 版异步资源守卫,可挂载到需要等待资源的 GameObject 上。 /// 典型用法:在 BattleField 上管理特效/Spine 的延迟播放。 /// public class AsyncResourceGuardBehaviour : MonoBehaviour { private readonly AsyncResourceGuard _guard = new AsyncResourceGuard(); public bool IsReady => _guard.IsReady; /// /// 标记资源就绪,触发所有排队播放。 /// public void SetReady() { _guard.SetReady(); } /// /// 提交一个播放请求:资源就绪则立即执行,否则排队。 /// public void Play(Action playAction) { if (this == null) return; _guard.EnqueueOrExecute(playAction); } /// /// 等待资源就绪。 /// public UniTask WaitUntilReady() { return _guard.WaitUntilReady(); } /// /// 重置守卫状态。 /// public void ResetGuard() { _guard.Reset(); } private void OnDestroy() { _guard.ClearPending(); } }