2017-04-26 78 views
1

我的代码:调用()不会被调用

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()代替。

回答

1

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

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

如果是这种情况,那么你必须把装载功能连接到独立游戏物体一个单独的脚本。当您致电Destroy(gameObject)时,该脚本不会破坏。

.Create一个新的游戏物体被称为“SceneLdObj”

。将以下脚本附加到“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>(); 
} 

,你可以从你的模功能的负载功能,它仍将即使游戏对象已经被销毁工作。

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

谢谢你正确预测我的意图。我之前忘了提及。我已成功按照步骤操作,“添加下面的脚本...”,但我不确定如何将给定的代码添加到我的代码中。我试过并在SceneLoader上出现错误。我需要首先声明SceneLoader吗?我应该声明哪种类型? – jer

+0

@jer将指令的最后部分直接修改到您的'Enemy'脚本中。只需复制一下。只要你创建了SceneLoader脚本并将其附加到名为*“SceneLdObj”*的新GameObject中。这应该工作。 – Programmer

+0

我只是最近使用stackoverflow.com。我不知道我必须接受。对不起。感谢您的高举。 :) – jer

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

我想补充一个'其他{销毁(本); ''以及。 – Draco18s