有些时候,比如做一个可能要被继承的类,可能不希望在这个类的Update方法里面添加内容,因为继承的子类一旦在Update里面填写内容,会覆盖父类的内容,这时候可以考虑使用递归协程的方法来模拟Update的效果,代码类似下面的写法:
using System.Collections;
using UnityEngine;
public class TT : MonoBehaviour
{
void OnEnable()
{
StartCoroutine(UpdateLoop());
}
int num = 0;
IEnumerator UpdateLoop()
{
yield return null;
Debug.Log(num++);
StartCoroutine(UpdateLoop());
}
}

协程的启动写在了OnEnable方法里面了,这样每次GameObject激活的时候都会启动协程,如果写到Start方法里面,如果GameObject不激活就会停止执行,即使再次激活也不会启动协程了。
还有一个需要说明的是停止这种递归协程的写法,请参考下面的代码:
Coroutine coroutineGetEquipmentInfoByID = null;
voidGetEquipmentInfoByID(bool isShow)
{
if (isShow)
{
coroutineGetEquipmentInfoByID = StartCoroutine(LoopGetEquipmentInfoByID());
}
else
{
if (coroutineGetEquipmentInfoByID != null)
{
StopCoroutine(coroutineGetEquipmentInfoByID);
coroutineGetEquipmentInfoByID = null;
}
}
}
UnityAction<int> onGetEquipmentInfoByID;
publicvoidAddActGetEquipmentInfoByID(UnityAction<int> act) { onGetEquipmentInfoByID -= act; onGetEquipmentInfoByID += act; }
publicvoidRemoveActGetEquipmentInfoByID(UnityAction<int> act) { onGetEquipmentInfoByID -= act; }
IEnumerator LoopGetEquipmentInfoByID()
{
onGetEquipmentInfoByID?.Invoke(equipment.equipmentID);
yieldreturnnewWaitForSeconds(interval);
coroutineGetEquipmentInfoByID = StartCoroutine(LoopGetEquipmentInfoByID());
}

注意里面的第6行和第25行有两行相同的代码,如下:
coroutineGetEquipmentInfoByID = StartCoroutine(LoopGetEquipmentInfoByID());
这样才能保证coroutineGetEquipmentInfoByID指向的是当前正在执行的协程,也就能保证停止的是当前正在执行的协程。