You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity协程中引用的成员字段变为NULL的问题排查

Unity协程中成员字段变为null的问题分析

第一段代码可以正常运行:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

class Enemy
{
    public string enemyName = "Default Enemy Name";
    TestGameObject_002 monoBehaviour = null;
    public Enemy(TestGameObject_002 monoBehaviour)
    {

    }
}

public class TestGameObject_002 : MonoBehaviour
{
    Enemy enemy = null;

    void Start()
    {   
        enemy = new Enemy(this);
        StartCoroutine(TestCoroutine());        
    }

    public IEnumerator TestCoroutine()
    {
        if(enemy != null)   Debug.Log("TestGameObject_002.TestCoroutine(), enemy is not null");
        else                Debug.Log("TestGameObject_002.TestCoroutine(), enemy is null");

        Debug.Log("TestGameObject_002.enemy.enemyName = " + enemy.enemyName);

        yield return null;
    }
}

但第二段代码会导致enemy变为null,协程引用的成员字段出现异常:

using System.Collections;
using System.Collections;
using UnityEngine;
using UnityEngine.Events;

class Enemy
{
    public string enemyName = "Default Enemy Name";
    TestGameObject_002 monoBehaviour = null;
    public Enemy(TestGameObject_002 monoBehaviour)
    {
        this.monoBehaviour = monoBehaviour;

        monoBehaviour.StartCoroutine(monoBehaviour.TestCoroutine());
    }
}

public class TestGameObject_002 : MonoBehaviour
{
    Enemy enemy = null;

    void Start()
    {   
        enemy = new Enemy(this);
    }

    public IEnumerator TestCoroutine()
    {
//yield return null;
        if(enemy != null)   Debug.Log("TestGameObject_002.TestCoroutine(), enemy is not null");
        else                Debug.Log("TestGameObject_002.TestCoroutine(), enemy is null");

        Debug.Log("TestGameObject_002.enemy.enemyName = " + enemy.enemyName);

        yield return null;
    }
}

问题原因

核心是变量赋值顺序和协程执行机制导致的:

  • 在第二段代码中,TestGameObject_002.Start()里执行enemy = new Enemy(this)时,会先调用Enemy的构造函数。
  • 构造函数内直接启动协程,协程的迭代器会立即执行到第一个yield之前的代码。
  • 但此时TestGameObject_002的enemy字段还没完成赋值——new Enemy(this)的构造逻辑还在执行中,enemy = ...的赋值要等构造函数完全结束后才会生效。
  • 所以协程执行时,enemy还是初始的null,触发空引用问题。
  • 如果在协程开头添加yield return null,会把协程的执行推迟到下一帧,此时enemy已经完成赋值,就能正常运行。

内容的提问来源于stack exchange,提问作者papyrus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 21:57:14