跳到主要内容

将协程与 GameObject 绑定

与 Unity 协程不同,winS.Unity.Coroutine 启动的协程不受 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;
}
}
}

此时,协程 PrintIDCoroutine 的生命周期将与组件所在的 gameObject 绑定,一旦 gameObject 被销毁,协程将自动停止。