将协程与 GameObject 绑定
与 Unity 协程不同,通过 winS.Unity.Coroutine 启动的协程不受UnityEngine.GameObject
生命周期影响。
此特性提供了更灵活的协程使用方式,且在大多数情况下可以正常工作,但也可能导致一些预期之外的问题,例如以下代码:
using System.Collections;
using UnityEngine;
using Coroutine = winS.Unity.Coroutine;
public class Example_ForGameObject_ErrorSample : MonoBehaviour
{
private void Start()
{
Coroutine.Start(PrintIDCoroutine);
}
private IEnumerator PrintIDCoroutine()
{
float time = 0f;
while (true)
{
if (time > 5f)
{
Debug.Log($"Name={gameObject.name}");
time = 0f;
}
yield return null;
time += Time.deltaTime;
}
}
}
在上述代码中,此组件在Start消息中启动协程,此协程每过5秒将组件所在的gameObject的名称打印在控制台中。
但是,如果组件所在的gameObject被其它代码销毁,则可能导致 MissingReferenceException。
这是由于gameObject已经被销毁,但协程没有停止,依然会间隔5秒访问GameObject.name属性。
对于类似上述的情景,您可能需要将协程的生命周期与 GameObject 的生命周期进行绑定。 为此,您可以在启动协程时向Coroutine.Start传入一个 GameObject 的实例。 我们修改上述代码:
using System.Collections;
using UnityEngine;
using Coroutine = winS.Unity.Coroutine;
public class Example_ForGameObject_ErrorSample : MonoBehaviour
{
private void Start()
{
Coroutine.Start(PrintIDCoroutine, gameObject);
}
private IEnumerator PrintIDCoroutine()
{
float time = 0f;
while (true)
{
if (time > 5f)
{
Debug.Log($"Name={gameObject.name}");
time = 0f;
}
yield return null;
time += Time.deltaTime;
}
}
}
winS.Unity.Coroutine 会在内部将协程协程函数与传入的 GameObject 进行绑定,一旦gameObject被销毁,协程将立刻停止。