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);elseInitialize(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);elseyield 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);elseyield 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;});
}

转载于:https://www.cnblogs.com/liusj/p/4048872.html

C# IEnumerator与 IEnumerable(2) 托管使用相关推荐

  1. C# IEnumerator和IEnumerable的区别

    C#有很多接口 ,这些接口牵扯一些复杂的算法问题,让很多新手对这些接口很难理解,尤其是IEnumerator和IEnumerable这两个接口,在IEnumeratorIEnumerable会让新手很 ...

  2. 2021年了,`IEnumerator`、`IEnumerable`接口还傻傻分不清楚?

    IEnumerator.IEnumerable这两个接口单词相近.含义相关,傻傻分不清楚. 入行多年,一直没有系统性梳理这对李逵李鬼. 最近本人在怼着why神的<其实吧,LRU也就那么回事> ...

  3. IEnumerator和IEnumerable

    IEnumerable和IEnumerator两个接口的语法定义.其实IEnumerable接口是非常的简单,只包含一个抽象的方法GetEnumerator(),它返回一个可用于循环访问集合的IEnu ...

  4. IEnumerator,IEnumerable,IEnumerableT

    1 接口IEnumerator,IEnumerable区别IEnumerable是一个声明式的接口,声明实现该接口的类就是"可迭代的enumerable",但并没用说明如 何实现迭 ...

  5. IEnumerator/ IEnumerable/ yield return/ StartCoroutine 详解

    Update逻辑 IEnumerator/ IEnumerable public interface IEnumerable { IEnumerator GetEnumerator(); } publ ...

  6. C# IEnumerator IEnumerable接口

    ​前言 使用linq的时候大家应该都知道IEnumerable和IEnumerator接口! 解释一下 IEnumerable 它利用 GetEnumerator() 返回 IEnumerator 集 ...

  7. Unity 新手入门 如何理解协程 IEnumerator yield

    Unity 新手入门 如何理解协程 IEnumerator 本文包含两个部分,前半部分是通俗解释一下Unity中的协程,后半部分讲讲C#的IEnumerator迭代器 协程是什么,能干什么? 为了能通 ...

  8. IEnumerable

    在平常的代码编写中,虽然不常用到Ienumerable 但却不可不知他的意义,有些时候使用会起到意想不到的作用, 我们从中可以知道 foreach 在IL中,是以Ienumberable 来体现的. ...

  9. 了解下 IEnumerable、ICollection、IList 和 IQueryable 接口

    在数据集合中,经常会用 IEnumerable.ICollection.IList 和 IQueryable 这些类型来定义变量和属性,今天就来了解下这些接口的特征及适用的场景. 以便我们增强代码的强 ...

  10. .NET(C#) Internals: .NET Framework中已使用的设计模式

    --适合有一定设计模式基础和.NET基础的人阅读. 写在前面 "设计模式"我一向是敬而远之的态度,不会去写这方面的文章,原因有二:第一,要想写好设计模式的文章太难,需要笔者丰富的经 ...

最新文章

  1. 用VS(c#)创建、调试windows service以及部署卸载
  2. R语言ggplot2可视化:使用geom_smooth函数基于lm方法为每个分组的部分数据(subset data)拟合趋势关系曲线、对指定范围的数据拟合曲线
  3. micropython安装第三方库_安装第三方模块
  4. Ehab and another construction problem(水题)
  5. AUTOSAR从入门到精通100讲(二十二)-AUTOSAR通信篇—CANTP模块
  6. “程序员千万不要选全栈开发”
  7. 32个Python爬虫项目
  8. Docker安装MySQL教程
  9. dialog的二次封装
  10. github 仓库中文名_Github仓库重命名
  11. IPSAN与FCSAN存储结构的区别
  12. v-model 自带绑定的number 、lazy 、debounce属性
  13. 迁移学习-域适应损失函数MMD-代码实现及验证
  14. 转载 测试面试问题总汇
  15. 小学三年级计算机画图工具作品,小学三年级美术下册《电脑绘画—模板帮我们作画》教案...
  16. html table tb左对齐,标签之美五——网页表格的设计
  17. 什么软件测试iphone性能,5款iPhone性能测试比拼:A9虽然垫底,与A13的差距并不大...
  18. 关于 Linux中系统调优的一些笔记
  19. VS2019+resharper2019.1免激活安装使用教程
  20. PCIE学习笔记(四)Xilinx FPGA PCI Express 硬核配置

热门文章

  1. 结合django动态生成salt的pillar数据
  2. js新建一个日期对象,指定日期值. 兼容IE8以下
  3. Web.config常用节点解析:
  4. ios应用程序开发框架
  5. 计算机硬盘是通用的吗,通用账务系统安装到计算机硬盘前需要进行的准备工作有()。A.清理硬盘B.校准计算机系统时间C.重设C - 作业在线问答...
  6. linux添加动态连接库,CentOS下如何添加动态链接库?
  7. java visibility_浅析Android中的visibility属性
  8. 【图解】虚拟机下载安装以及Linux操作系统的配置CentOS安装
  9. SpringBoot配置参数绑定@ConfigurationProperties@Value
  10. ERROR 1820: You must reset your password using ALTER USER statement before executing this statement