C# IEnumerator与 IEnumerable(2) 托管使用
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) 托管使用相关推荐
- C# IEnumerator和IEnumerable的区别
C#有很多接口 ,这些接口牵扯一些复杂的算法问题,让很多新手对这些接口很难理解,尤其是IEnumerator和IEnumerable这两个接口,在IEnumeratorIEnumerable会让新手很 ...
- 2021年了,`IEnumerator`、`IEnumerable`接口还傻傻分不清楚?
IEnumerator.IEnumerable这两个接口单词相近.含义相关,傻傻分不清楚. 入行多年,一直没有系统性梳理这对李逵李鬼. 最近本人在怼着why神的<其实吧,LRU也就那么回事> ...
- IEnumerator和IEnumerable
IEnumerable和IEnumerator两个接口的语法定义.其实IEnumerable接口是非常的简单,只包含一个抽象的方法GetEnumerator(),它返回一个可用于循环访问集合的IEnu ...
- IEnumerator,IEnumerable,IEnumerableT
1 接口IEnumerator,IEnumerable区别IEnumerable是一个声明式的接口,声明实现该接口的类就是"可迭代的enumerable",但并没用说明如 何实现迭 ...
- IEnumerator/ IEnumerable/ yield return/ StartCoroutine 详解
Update逻辑 IEnumerator/ IEnumerable public interface IEnumerable { IEnumerator GetEnumerator(); } publ ...
- C# IEnumerator IEnumerable接口
前言 使用linq的时候大家应该都知道IEnumerable和IEnumerator接口! 解释一下 IEnumerable 它利用 GetEnumerator() 返回 IEnumerator 集 ...
- Unity 新手入门 如何理解协程 IEnumerator yield
Unity 新手入门 如何理解协程 IEnumerator 本文包含两个部分,前半部分是通俗解释一下Unity中的协程,后半部分讲讲C#的IEnumerator迭代器 协程是什么,能干什么? 为了能通 ...
- IEnumerable
在平常的代码编写中,虽然不常用到Ienumerable 但却不可不知他的意义,有些时候使用会起到意想不到的作用, 我们从中可以知道 foreach 在IL中,是以Ienumberable 来体现的. ...
- 了解下 IEnumerable、ICollection、IList 和 IQueryable 接口
在数据集合中,经常会用 IEnumerable.ICollection.IList 和 IQueryable 这些类型来定义变量和属性,今天就来了解下这些接口的特征及适用的场景. 以便我们增强代码的强 ...
- .NET(C#) Internals: .NET Framework中已使用的设计模式
--适合有一定设计模式基础和.NET基础的人阅读. 写在前面 "设计模式"我一向是敬而远之的态度,不会去写这方面的文章,原因有二:第一,要想写好设计模式的文章太难,需要笔者丰富的经 ...
最新文章
- 用VS(c#)创建、调试windows service以及部署卸载
- R语言ggplot2可视化:使用geom_smooth函数基于lm方法为每个分组的部分数据(subset data)拟合趋势关系曲线、对指定范围的数据拟合曲线
- micropython安装第三方库_安装第三方模块
- Ehab and another construction problem(水题)
- AUTOSAR从入门到精通100讲(二十二)-AUTOSAR通信篇—CANTP模块
- “程序员千万不要选全栈开发”
- 32个Python爬虫项目
- Docker安装MySQL教程
- dialog的二次封装
- github 仓库中文名_Github仓库重命名
- IPSAN与FCSAN存储结构的区别
- v-model 自带绑定的number 、lazy 、debounce属性
- 迁移学习-域适应损失函数MMD-代码实现及验证
- 转载 测试面试问题总汇
- 小学三年级计算机画图工具作品,小学三年级美术下册《电脑绘画—模板帮我们作画》教案...
- html table tb左对齐,标签之美五——网页表格的设计
- 什么软件测试iphone性能,5款iPhone性能测试比拼:A9虽然垫底,与A13的差距并不大...
- 关于 Linux中系统调优的一些笔记
- VS2019+resharper2019.1免激活安装使用教程
- PCIE学习笔记(四)Xilinx FPGA PCI Express 硬核配置
热门文章
- 结合django动态生成salt的pillar数据
- js新建一个日期对象,指定日期值. 兼容IE8以下
- Web.config常用节点解析:
- ios应用程序开发框架
- 计算机硬盘是通用的吗,通用账务系统安装到计算机硬盘前需要进行的准备工作有()。A.清理硬盘B.校准计算机系统时间C.重设C - 作业在线问答...
- linux添加动态连接库,CentOS下如何添加动态链接库?
- java visibility_浅析Android中的visibility属性
- 【图解】虚拟机下载安装以及Linux操作系统的配置CentOS安装
- SpringBoot配置参数绑定@ConfigurationProperties@Value
- ERROR 1820: You must reset your password using ALTER USER statement before executing this statement