1. 首先创建单例模式类
using System; using UnityEngine; // 首先定义一个单例模式类并且也继承MonoBehaviour public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T> { private static T instance = null; //单例模式变量 public static T Instance //变量get方法 { get { if (instance != null) return instance; //空判断 Type type = typeof(T); // T localInstance = GameObject.FindObjectOfType(type) as T; // 检测实例是否存在 if (localInstance == null) { string typeName = type.ToString(); var gameObject = new GameObject(typeName, type); localInstance = gameObject.GetComponent<T>(); if (localInstance == null) Debug.LogError("Problem during the creation of " + typeName, gameObject); else Initialize(localInstance); } return instance; } } // 第一次创建的时候 对创建类进行一下关联的初始化 private static void Initialize(T localInstance) { if (instance == null) { instance = localInstance; instance.OnInitialize(); OnInstanceReady(); } else if (instance != localInstance) { DestroyImmediate(localInstance.gameObject); //如果创建的类和存在的类不一致 则立即收回资源 } } protected virtual void Awake() // 虚函数 创建实例的类 挂在对象加载时 如果不重写Awake方法 单例实例会被立刻创建 { Initialize(this as T); } private void OnApplicationQuit() // 销毁的执行顺序 OnApplicationQuit OnDisable OnDestroy { Destroyed(this as T); } private void OnDisable() { Destroyed(this as T); } private void OnDestroy() { Destroyed(this as T); } private static void Destroyed(T localInstance) { if (instance == localInstance) { instance.OnFinalize(); instance = null; } } public virtual void OnInitialize() {} //虚函数 创建实例的类 创建时可以重写此方法 创建后可执行初始化 public virtual void OnFinalize() {} //虚函数 创建实例的类 创建时可以重写此方法 销毁对象之前会调用 /////////////////////////////////////////////////////////////////////// public static bool Exists { get { return instance != null; } } public static bool IsInstanceReady { get { return instance != null; } } //////////////////////////////单例被创建后 调用Event事件进行相应处理 ///////////////////////////////////////// public static event EventHandler InstanceReady; private static void OnInstanceReady() { var handler = InstanceReady; if (handler != null) handler(null, EventArgs.Empty); } }
2. Scheduler 执行顺序管理类
using UnityEngine; using System.Collections; using System.Collections.Generic; using System; public class Scheduler : MonoSingleton<Scheduler> { private Queue<Action> tasks = new Queue<Action>(); // Queue(队列)类主要实现了一个FIFO(First In First Out,先进先出)的机制 //1. 挂在对象启动后 实例化单例模式 //2. 当加载一个新关卡时,所有场景中所有的物体被销毁,然后新关卡中的物体被加载进来。 // 为了保持在加载新关卡时物体不被销毁,使用DontDestroyOnLoad保持, // 如果物体是一个组件或游戏物体,它的整个transform层次将不会被销毁,全部保留下来。 protected virtual void Awake() { base.Awake(); DontDestroyOnLoad(this); } public void Schedule(Action task) { if (task == null) return; lock (tasks) tasks.Enqueue(task); } public Coroutine AwaitNextFrame(Action onDone) { if (onDone == null) return null; return StartCoroutine(AwaitNextFrameInternal(onDone)); } public Coroutine AwaitForSeconds(float seconds, Action onDone) { if (seconds < 0.0f || onDone == null) return null; return StartCoroutine( x => x.Return = new WaitForSeconds(seconds), x => onDone()); } public Coroutine While(Func<bool> statement, Action onDone) { if (statement == null || onDone == null) return null; return StartCoroutine(RunWhile(statement, onDone)); } public Coroutine StartCoroutine(params Func<object>[] statements) { if (statements.Length == 0) return null; return StartCoroutine(RunStatements(statements)); } public Coroutine StartCoroutine(params Action<ReturnValue>[] statements) { if (statements.Length == 0) return null; return StartCoroutine(RunStatements(statements)); } // === privates ================================================================ private void Update() { lock (tasks) { int throttle = 15; while (tasks.Count > 0 && throttle > 0) { tasks.Dequeue()(); throttle--; } } } private static IEnumerator RunStatements(Func<object>[] statements) { foreach (var statement in statements) { var st = statement(); if (st is IEnumerator) yield return Scheduler.Instance.StartCoroutine((IEnumerator)st); else yield return st; } } private static IEnumerator RunStatements(Action<ReturnValue>[] statements) { foreach (var statement in statements) { var param = new ReturnValue(); statement(param); if (param.Return is IEnumerator) yield return Scheduler.Instance.StartCoroutine((IEnumerator)param.Return); else yield return param.Return; } } private static IEnumerator RunWhile(Func<bool> statement, Action onDone) { while (statement()) yield return null; onDone(); } private static IEnumerator AwaitNextFrameInternal(Action callback) { yield return null; callback(); } public class ReturnValue { public object Return; } }
3 使用方式
使用方式1
Scheduler.Instance.StartCoroutine(InitializeBattleAsync()); private IEnumerator InitializeBattleAsync() { battleCharacterManager = new BattleCharacterManager(); yield return battleCharacterManager.CreateRawGameObject( new CharacterCreationInfo(CharacterType.Summon, CharacterClass.SummonDragon), go => { summon = go; //托管 第五步执行 summon.SetActive(false); }); }
public class BattleCharacterManager : IBattleCharacterManager { // 逻辑函数第二步调用 CreateOneCharacterInstanceAsync 执行结束后返回 public YieldInstruction CreateRawGameObject(CharacterCreationInfo characterCreationInfo, Action<GameObject> whenDone) { return Scheduler.Instance.StartCoroutine(CreateOneCharacterInstanceAsync(characterCreationInfo, whenDone)); } // 逻辑处理函数第三部调用 private IEnumerator CreateOneCharacterInstanceAsync(CharacterCreationInfo info, Action<GameObject> whenDone) { if (whenDone == null) throw new ArgumentNullException("whenDone"); UnityEngine.Object prefab = null; if (characterPrefabs.TryGetValue(info.CharacterClass, out prefab) == false) { var basePath = BattleConstants.CharacterConstants.CharacterPrefabsPath; if (info.CharacterType == CharacterType.Summon) basePath = BattleConstants.CharacterConstants.SummonPrefabsPath; var prefabFullPath = basePath + ResolvePrefabName(info); var resourceRequest = Resources.LoadAsync(prefabFullPath); yield return resourceRequest; yield return null; prefab = resourceRequest.asset; if (prefab == null) throw new InvalidOperationException("Impossible to find prefab ‘" + prefabFullPath + "‘"); characterPrefabs.Add(info.CharacterClass, prefab); } var instance = GameObject.Instantiate(prefab) as GameObject; if (instance == null) throw new InvalidOperationException("Impossible to create instance of prefab ‘" + info.CharacterClass + "‘"); // 托管执行 whenDone(instance); } }
使用方式2
void battleWin { SceneManager.Instance.RootStateMachine.PerformAction(RootActionTokens.Next); // result win Scheduler.Instance.StartCoroutine( x => x.Return = new WaitForSeconds(0.5f), x => BattleResult.Instance.BattleWin()); return; }
使用方式3 :
private void RunAwaiter(CharacterAnimationStates state, Action whenDone) { Scheduler.Instance.While( () => { if (previousState != state) { RequestAction(state); return true; } return false; }, () => { if (whenDone != null) whenDone(); }); }
使用方式4
public void UnloadCurrentMap() { Scheduler.Instance.AwaitNextFrame( () => { OnMapUnloaded(new MapEventArgs(CurrentStage, StartPositions)); CurrentStage = Stages.None; }); }
时间: 2024-11-10 22:11:33