Invoke()不会被调用

时间:2017-04-26 12:28:31

标签: c# unity3d unity5

我的代码:

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(),但我想改用 A sequence B sequence C sequence Target sequence

2 个答案:

答案 0 :(得分:2)

问题是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)(将在一秒钟后销毁对象)。

答案 1 :(得分:1)

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

然而,我有一种感觉,你想要立即销毁该对象而不等待,因为你希望该脚本中的东西(例如OnCollisionEnter2D)停止运行,但同时想要加载场景稍后的。

如果是这种情况,则必须将加载功能放在单独的游戏对象单独脚本中。当您致电Destroy(gameObject)时,此脚本不会销毁。

1 。创建一个名为&#34; SceneLdObj&#34; 的新GameObject。

2 。将下面的脚本附加到&#34; SceneLdObj&#34;游戏对象。

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函数加载函数,即使游戏对象已经被破坏,它仍然可以正常工作。

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