曾被问道 Unity 协程是如何知道条件是否满足的。
直到看了一个讲师的视频后才明白一些。
IEnumerator 迭代器是一个容器,可以装一个一个的函数,
依次执行每个函数(即:MoveNext()),每个函数会有一个返回值,
返回值会保存在 IEnumerator.Current对象里。
yield return null;
yield 是单独存在的,yield是yield,return null是return null。 yield做了什么事情呢?
yield把它之前的代码 “Debug.Log("111111111");”和 “return 1;”做成一个函数放到IEnumerator容器中
然后在更新函数里每帧判断是否满足条件,满足就开始执行下一个函数。
由于对C#语言还做不到深入的理解,迭代器到底咋回事不清楚,所以讲师讲到的明白,其它的条件还是不会实现。
以下是测试代码:
public class CoroutineTest : MonoBehaviour
{
IEnumerator e = null;
//IEnumerator 迭代器是一个容器,可以装一个一个的函数,
//依次执行每个函数,每个函数会有一个返回值,
//返回值会保存在 IEnumerator.Current对象里。
//yield return null;
//yield 是单独存在的,yield是yield,return null是return null。 yield做了什么事情呢?
//yield把它之前的代码 “Debug.Log("111111111");”和 “return 1;”做成一个函数放到IEnumerator容器中
//function0()
//{
// Debug.Log("111111111");
// return 1;
//}
//function1()
//{
// Debug.Log("22222222");
// return 2;
//}
//function2()
//{
// Debug.Log("我要睡5秒钟");
// return new WaitForSeconds(5);
//}
IEnumerator start_Coroutine()
{
Debug.Log("111111111");
yield return 1;
Debug.Log("22222222");
yield return 2;
Debug.Log("我要睡5秒钟");
yield return new ClassWaitForTime(5);
Debug.Log("我醒了");
yield break;//yield break是一起的吗?
}
void Start()
{
e = start_Coroutine();
//while (e.MoveNext())//执行当前的函数,返回值存放到IEnumerator.Current并把位置拨动到下一个
//{
// Debug.Log(e.Current);
//}
}
private void LateUpdate()
{
if (e != null)
{
if (e.Current is ClassWaitForTime)
{
ClassWaitForTime wt = e.Current as ClassWaitForTime;
wt.Update(Time.deltaTime);
if (!wt.IsOver())
{
return;//如果时间没有到,就不往后面执行
}
}
if (!e.MoveNext()) //如果枚举数已成功地推进到下一个元素,则为 true;如果枚举数传递到集合的末尾,则为 false。
{
e = null;
}
}
}
}
//自己实现一个类似 new WaitForSeconds()
public class ClassWaitForTime
{
private float total;
private float now;
public ClassWaitForTime(float time)
{
total = time;
now = 0;
}
public void Update(float dt)
{
now += dt;
}
public bool IsOver()
{
return now >= total;
}
}