Unity协程队列,顺序分帧处理
来源:互联网 发布:php 通过域名获取ip 编辑:程序博客网 时间:2024/06/05 08:55
游戏开发过程中经常会遇到要加载一片场景资源的情况,先不考虑如何加载的情况,对于一大片场景的加载和显示,如果在一帧内完成的话,对性能会有很大的小号,造成瞬间帧率下降,产生性能峰值。
一般这种不需要实时性的加载都会分帧处理,把压力平摊下去,为了使加载过程更加平滑与受控,博主写一个协程队列去控制我们加载过程中协程的调用顺序与次数,更好的平滑我们的加载过程。
因为这里协程的调用是使用迭代器的MoveNext,并非调用StartCoroutine开启动迭代器,所以无法实现计时器的功能(WaitForSeconds),仅支持yield return null,能够满足此条件的才能使用该脚本,同时这种实现方法也带来性能优势,减少每次调用一次StartCoroutine都会带来24B的内存消耗,若开启协程很平凡,这个消耗还是很明显的。
使用方法是找个GameObject挂载CoroutineManager脚本,需要管理的协程通过CoroutineManager.EnqueueWork方法加到协程队列,下面源码中也有测试代码。
协程队列处理:
EnqueueWork(Test1());
EnqueueWork(Test3());
EnqueueWork(Test3());
正常开启协程:
StartCoroutine(Test1());
StartCoroutine(Test3());
StartCoroutine(Test3());
可以看出,使用协程队列可以更加平滑而且容易控制的去控制协程。
using UnityEngine;using System.Collections;using System.Collections.Generic;public class CoroutineManager : MonoBehaviour{ //协程队列 private QueuemCoroutineQueue = new Queue (); //当前处理的协程 private IEnumerator mCurrentWork = null; private static CoroutineManager instance; public static CoroutineManager Instance { get { return instance; } } void Awake() { instance = this; } public void EnqueueWork(IEnumerator work) { mCoroutineQueue.Enqueue(work); } void Update() { while (mCoroutineQueue.Count > 30) DoWork(); //如果协程队列>20个,则一次执行3个语块 if (mCoroutineQueue.Count > 20) DoWork(); //如果协程队列>10个,则一次执行2个语块 if (mCoroutineQueue.Count > 10) DoWork(); DoWork(); } void DoWork() { if (mCurrentWork == null && mCoroutineQueue.Count == 0) return; if (mCurrentWork == null) { mCurrentWork = mCoroutineQueue.Dequeue(); } //这个协程片段是否执行完毕 bool mElementFinish = !mCurrentWork.MoveNext(); if (mElementFinish) { mCurrentWork = null; } //如果协程里面嵌套协程 else if (mCurrentWork.Current is IEnumerator) { mCurrentWork = (mCurrentWork.Current as IEnumerator); } } #region 这一部分为测试代码 void Start() { //协同队列处理 EnqueueWork(Test1()); EnqueueWork(Test3()); //正常开启协同 //StartCoroutine(Test1()); //StartCoroutine(Test3()); } IEnumerator Test1() { Debug.Log(string.Format("第{0}帧:1",Time.frameCount)); yield return null; Debug.Log(string.Format("第{0}帧:2", Time.frameCount)); yield return null; Debug.Log(string.Format("第{0}帧:3", Time.frameCount)); yield return Test2(); } IEnumerator Test2() { Debug.Log(string.Format("第{0}帧:4", Time.frameCount)); yield return null; Debug.Log(string.Format("第{0}帧:5", Time.frameCount)); yield return null; Debug.Log(string.Format("第{0}帧:6", Time.frameCount)); } IEnumerator Test3() { Debug.Log(string.Format("第{0}帧:7", Time.frameCount)); yield return null; Debug.Log(string.Format("第{0}帧:8", Time.frameCount)); yield return null; Debug.Log(string.Format("第{0}帧:9", Time.frameCount)); } #endregion}
阅读全文
0 0
- Unity协程队列,顺序分帧处理
- unity执行顺序以及unity协程的使用
- UNITY 3D 协程执行顺序
- 探寻Unity协程执行的顺序
- 顺序队列
- 顺序队列
- 顺序队列
- 顺序队列
- 顺序队列
- 顺序队列
- 顺序队列
- 顺序队列
- 顺序队列
- 顺序队列
- 顺序队列
- 顺序队列
- 顺序队列
- 顺序队列
- 深入理解PHP:高级技巧、面向对象与核心技术(原书第3版) -- 设计模式之策略模式
- Python进阶—map函数
- python代码优化
- 分布式和集群的区别
- Android 使用volley上传图片、多张图片
- Unity协程队列,顺序分帧处理
- int、long、long long、unsigned int、_int64的取值范围(与不同位数的编译器有关)
- 利用ajax对页面局部刷新
- 在一个千万级的数据库查寻中,如何提高查询效率?
- 如何让你的浏览器没有广告?
- UE4 Login相关代码
- 【C++ Primer Plus】指针
- bzoj2142 礼物
- 2017年9月感触