Invoke() 没有被调用

Invoke() does not get called

我的代码:

public class Enemy : MonoBehaviour 
{
    public GameObject deathEffect;
    public float health = 4f;
    public static int EnemiesAlive = 0;
    public int loadToScene;

    void Start ()
    {
        EnemiesAlive++;
    }

    void OnCollisionEnter2D (Collision2D colInfo)
    {
        if (colInfo.relativeVelocity.magnitude > health)
        {
            Die();
        }
    }

    void Die ()
    {
        Instantiate(deathEffect, transform.position, Quaternion.identity);
        EnemiesAlive--;

        if (EnemiesAlive <= 0)
        {
            Debug.Log ("LEVEL WON!");
            Invoke("ChangeScene",2f);
        }
        Destroy(gameObject);
    }

    void ChangeScene()
    {
        Debug.Log ("Hello");
        loadToScene = 1;
        SceneManager.LoadScene (loadToScene);
    }
}

谁能告诉我为什么 Invoke() 不起作用?一旦满足条件 (EnemiesAlive <= 0),我想在更改场景之前添加 2 秒延迟。 Debug.Log ("LEVEL WON!"); 输出,而 Debug.Log ("Hello"); 不输出。我知道我也可以使用 StartCoroutine,但我想改用 Invoke()

问题是 Invoke 实际上被调用了,但是你的对象在被调用的方法执行之前被销毁了。
要解决这个问题,请将 Destroy(gameObject) 移动到 ChangeScene 方法:

void Die ()
{
    Instantiate(deathEffect, transform.position, Quaternion.identity);
    EnemiesAlive--;

    if (EnemiesAlive <= 0)
    {
        Debug.Log ("LEVEL WON!");
        Invoke("ChangeScene",2f);
    }
}

void ChangeScene()
{
    Debug.Log ("Hello");
    loadToScene = 1;
    Destroy(gameObject);
    SceneManager.LoadScene (loadToScene);
}

您可以选择使用 Destroy 方法的重载来指定销毁对象的时间:Destroy(gameObject, 1.0f)(将在一秒后销毁对象)。

那是因为你像 提到的那样调用 Destroy(gameObject) 并且它没有机会执行 Invoke("ChangeScene",2f);.

但是,我有一种感觉,您想立即销毁该对象而无需等待,因为您希望该脚本中的内容(例如 OnCollisionEnter2D)停止 运行 但同时时间想稍后加载您的场景。

如果是这种情况,那么您必须将加载函数放在附加到单独游戏对象单独脚本中。当您调用 Destroy(gameObject).

时,此脚本不会销毁

1.创建一个名为 "SceneLdObj".

的新游戏对象

2。将下面的脚本附加到 "SceneLdObj" 游戏对象。

public class SceneLoader : MonoBehaviour
{
    int loadToScene = 1;
    public void ChangeScene(int sceneLevel)
    {
        loadToScene = sceneLevel;
        Invoke("loadScene", 2f);
    }

    private void loadScene()
    {
        SceneManager.LoadScene(loadToScene);
    }
}

将下面的脚本添加到您问题中的脚本中:

 SceneLoader sceneLoader;

 void Start()
 {
     sceneLoader = GameObject.Find("SceneLdObj").GetComponent<SceneLoader>();
 }

现在,您可以从 Die 函数中加载函数,即使 GameObject 已经被销毁,它仍然可以工作。

void Die()
{
    Instantiate(deathEffect, transform.position, Quaternion.identity);
    EnemiesAlive--;

    if (EnemiesAlive <= 0)
    {
        Debug.Log("LEVEL WON!");
        //Call that function from another script
        sceneLoader.ChangeScene(1);
    }
    Destroy(gameObject);
}

编辑

这应该是您的新 Enemy 脚本:

public class Enemy : MonoBehaviour 
{
    public GameObject deathEffect;
    public float health = 4f;
    public static int EnemiesAlive = 0;
    public int loadToScene;
    SceneLoader sceneLoader;

    void Start ()
    {
        sceneLoader = GameObject.Find("SceneLdObj").GetComponent<SceneLoader>();
        EnemiesAlive++;
    }

    void OnCollisionEnter2D (Collision2D colInfo)
    {
        if (colInfo.relativeVelocity.magnitude > health)
        {
            Die();
        }
    }

    void Die ()
    {
        Instantiate(deathEffect, transform.position, Quaternion.identity);
        EnemiesAlive--;

        if (EnemiesAlive <= 0)
        {
            Debug.Log ("LEVEL WON!");
            //Call that function from another script
            sceneLoader.ChangeScene(1);
        }
        Destroy(gameObject);
    }

    void ChangeScene()
    {
        Debug.Log ("Hello");
        loadToScene = 1;
        SceneManager.LoadScene (loadToScene);
    }
}