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