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);
}
}
我的代码:
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)
(将在一秒后销毁对象)。
那是因为你像 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);
}
}