Unity自定义协同程序多线程lambada等
unity coroutine calldelay定时器原理 在此基础上,进一步
继承UserTypeWait 即可使用自定义的协同程序等待事件,自定义实现类似于WaitForSeconds 或者WWW 或者LoadLevelAsync等一样用法的时间,注意这个Loop是同步写法,如果要真正异步,请在内部用多线程包装一下即可,多线程版本版本4已实现(该方案也许是多核优化的一个思路),版本3是lambada版本,
总之想怎么玩就怎么玩
版本1 类写法1
using UnityEngine; using System.Collections; using System; public class UserTypeWait { public IEnumerator Wait() { while (Loop()) { yield return null; } } public virtual bool Loop() { return false; } } public class WaitForTickCount50 : UserTypeWait { public override bool Loop() { ++c; if (c > 50) { return false; } return true; } int c = 0; } public class NewBehaviourScript : MonoBehaviour { void Start() { StartCoroutine(Run1()); } IEnumerator Run1() { Debug.LogError("1111111"); yield return new WaitForTickCount50().Wait(); Debug.LogError("2222222222"); } } 版本2 类写法2 using UnityEngine; using System.Collections; using System; public class UserTypeWait:IEnumerator { public bool MoveNext() { return Loop(); } public void Reset() { } public object Current { get { return null; } } public virtual bool Loop() { return true; } } public class WaitForTickCount50 : UserTypeWait { public override bool Loop() { ++c; if (c > 50) { return false; } return true; } int c = 0; } public class NewBehaviourScript : MonoBehaviour { void Start() { StartCoroutine(Run1()); } IEnumerator Run1() { Debug.LogError("1111111"); yield return new WaitForTickCount50(); Debug.LogError("2222222222"); } } 版本3,lambada写法 using UnityEngine; using System.Collections; using System; public class UserTypeWait : IEnumerator { public bool MoveNext() { return Loop(); } public void Reset() { } public object Current { get { return null; } } public virtual bool Loop() { return false; } } public delegate bool BoolFuncVoid(); public class WaitForLambada : UserTypeWait { BoolFuncVoid cb; public WaitForLambada(BoolFuncVoid cb) { this.cb = cb; } public override bool Loop() { if (cb == null) { return false; } return cb(); } int c = 0; } public class NewBehaviourScript : MonoBehaviour { void Start() { StartCoroutine(Run1()); } IEnumerator Run1() { Debug.LogError("1111111"); int c = 0; yield return new WaitForLambada(() => { c++; if (c > 50) return false; return true; }); Debug.LogError("2222222222"); } }
版本4 多线程,多线程写法是 某种程度上真正的异步,逻辑上的同步写法,代码却是thread执行, 同步写法 异步执行,多核优化也可以更简单,如添加WaitForThreadJobGroup 这种
using UnityEngine; using System.Collections; using System; public class UserTypeWait : IEnumerator { public bool MoveNext() { return Loop(); } public void Reset() { } public object Current { get { return null; } } public virtual bool Loop() { return false; } } public delegate bool BoolFuncVoid(); public delegate void VoidFuncVoid(); public class WaitForThreadJob : UserTypeWait { bool isDone = false; public override bool Loop() { return !isDone; } System.Threading.Mutex locker = new System.Threading.Mutex(); public WaitForThreadJob(VoidFuncVoid job) { thread = new System.Threading.Thread(new System.Threading.ThreadStart(() => { job(); locker.WaitOne(); isDone = true; locker.ReleaseMutex(); })); thread.Start(); } System.Threading.Thread thread; } public class NewBehaviourScript : MonoBehaviour { void Start() { StartCoroutine(Run1()); } IEnumerator Run1() { Debug.LogError("1111111"); int c = 0; yield return new WaitForThreadJob(() => { for (int i = 0; i < 3000000; i++) { Vector3.Distance(Vector3.zero, Vector3.one); Vector3.Distance(Vector3.zero, Vector3.one); Vector3.Distance(Vector3.zero, Vector3.one); Vector3.Distance(Vector3.zero, Vector3.one); Vector3.Distance(Vector3.zero, Vector3.one); Vector3.Distance(Vector3.zero, Vector3.one); Vector3.Distance(Vector3.zero, Vector3.one); Vector3.Distance(Vector3.zero, Vector3.one); } }); Debug.LogError("2222222222"); } }
类似的功能Unity集成了的有 WaitWhile ,WaitUntil ,CustomYieldInstruction