在Unity引擎中,协程引用的成员字段变为NULL

问题描述 投票:0回答:1

这段代码运行良好。

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;
    }
}

但是由于某种原因,下面的代码使敌人为空。协程引用的成员字段变成了NULL。很难理解为什么,因为我不认为通过引用传递 MonoBehavior 并调用 StartCoroutine 会导致任何问题。

正如预期的那样,下面的代码应该可以正常工作。

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)
    {
        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;
    }
}

如果在引用敌人之前将控制权返回到使用yield的unity循环,则效果很好。

c# unity-game-engine unity-container coroutine unityscript
1个回答
0
投票

您的问题是由于敌人变量的赋值时间与协程的启动时间不匹配而引起的。在 Enemy 构造函数中启动协程并尝试访问尚未分配的敌人变量会导致敌人为空。 要解决这个问题: 你可以通过添加yield return null让协程等到敌人被分配为止;在协程的开始处。 或者,您可以在分配敌人后启动协程。

public class TestGameObject_002 : MonoBehaviour
{
    Enemy enemy = null;

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

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

        Debug.Log("TestCoroutine() enemy name: " + enemy.enemyName);

        yield return null;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.