前两天被人问到Unity里协程实现原理,问的我哑口无言,这几天闲下来特意去查了一下,主要是使用c#的迭代器模式,感觉自己对unity了解还是不够深入啊...
好了,下面是代码,参考了某位前辈的文章https://www.cnblogs.com/yougoo/p/9565704.html
class Program
{
static void Main(string[] args)
{
CoroutineManager.Instance.StartCoroutine(TestIE1());
CoroutineManager.Instance.StartCoroutine(TestIE2());
bool start = true;
while (start)
{
Thread.Sleep(Time.deltaMillisecond);
CoroutineManager.Instance.UpdateCoroutine();
}
Console.ReadKey(true);
}
public static IEnumerator TestIE1()
{
yield return new WaitForFrames(5);
Console.WriteLine("这是第五帧");
}
public static IEnumerator TestIE2()
{
for (int i = 0; i < 3; i++)
{
Console.WriteLine(i);
yield return new WaitForSecond(3);
}
}
}
public class Time
{
public static float deltaTime
{
get { return (float)deltaMillisecond / 1000; }
}
public static int deltaMillisecond
{
get { return 20; }
}
}
public class CoroutineManager
{
public static CoroutineManager Instance
{
get
{
if (m_Instance == null)
{
m_Instance = new CoroutineManager();
}
return m_Instance;
}
}
private static CoroutineManager m_Instance;
private LinkedList<IEnumerator> coroutineList = new LinkedList<IEnumerator>();
public void StartCoroutine(IEnumerator enumerator)
{
coroutineList.AddLast(enumerator);
}
public void StopCoroutine(IEnumerator enumerator)
{
if(coroutineList.Contains(enumerator))
coroutineList.Remove(enumerator);
else
Console.WriteLine("错误,没有需要移除的 IEnumerator");
}
public void UpdateCoroutine()
{
var node = coroutineList.First;
while (node!=null)
{
IEnumerator ie = node.Value;
bool ret = true;
if (ie.Current is IWait)
{
IWait wait = (IWait)ie.Current;
if (wait.Tick())
{
ret = ie.MoveNext();
}
}
else
{
ret= ie.MoveNext();
}
if (!ret)
{
coroutineList.Remove(node);
}
node = node.Next;
}
}
}
public interface IWait
{
bool Tick();
}
public class WaitForSecond:IWait
{
private float m_Second = 0;
public WaitForSecond(float Second)
{
this.m_Second = Second;
}
public bool Tick()
{
m_Second -= Time.deltaTime;
return m_Second <= 0;
}
}
public class WaitForFrames : IWait
{
private int m_Frames = 0;
public WaitForFrames(int frames)
{
this.m_Frames = frames;
}
public bool Tick()
{
m_Frames -= 1;
return m_Frames <= 0;
}
}