我試圖引爆一枚手榴彈(它正在作業),然后在延遲后,從場景中移除損壞的物體,以清除玩家正在看的東西。因為延遲只需要在手榴彈爆炸后才開始,所以我不能在 Update() 函式中使用計時器設定,正如這里的其他解決方案所建議的那樣(就像你可以看到我正在為引爆倒計時所做的那樣).
Invoke() 也不起作用,因為我需要將附近的物件碰撞器作為引數傳遞。我一直在尋找解決方案一天,但我無法讓它發揮作用。
我的代碼在這里:
public class Grenade : MonoBehaviour
{
public float delay = 3f;
private float countdown;
private bool hasExploded = false;
public GameObject explosionEffect;
public float explosionForce;
public float damageRadius;
public float destroyDelayTime = 3.0f;
void Start()
{
countdown = delay;
}
void Update()
{
// start countdown
countdown -= Time.deltaTime;
// run explode method
if (countdown <= 0 && !hasExploded)
{
Explode();
hasExploded = true;
}
}
private void Explode()
{
// Show explosion effect (cut out to simplify my question, but works fine)
// Get nearby objects
Collider[] colliders = Physics.OverlapSphere(transform.position, damageRadius);
// Apply explosion force to each object (again cut out, but works fine)
// destroy grenade object
Destroy(gameObject);
Debug.Log("Grenade destroyed");
// destroy nearby objects after a delay
StartCoroutine(DelayObjectDestroy(colliders, destroyDelayTime));
}
IEnumerator DelayObjectDestroy(Collider[] colliders, float delay)
{
Debug.Log("DelayObjectDestroy called");
yield return new WaitForSeconds(3.0f); // will replace 3.0f with 'delay' once it is working
Debug.Log("Objects destroyed");
}
}
該Debug.Log("DelayObjectDestroy called");行顯示在控制臺中,所以我知道協程確實被呼叫了。Debug.Log("Objects destroyed");盡管等待了很長時間,但該行并未顯示在控制臺中。
除了 MonoBehaviour 之外沒有超類,并且控制臺中沒有出現任何錯誤。
更讓我困惑的是,我制作了一個新的、簡單的腳本并將其附加到相機上,只是為了看看協程是否可以作業,而且它完全按照它應該的方式作業。為什么此代碼有效但我的手榴彈腳本卻無效?
public class camera : MonoBehaviour
{
void Start()
{
StartCoroutine(meh());
}
private IEnumerator meh()
{
Debug.Log("Game started");
yield return new WaitForSeconds(8.0f);
Debug.Log("Game ended");
}
}
開始時,控制臺顯示“游戲開始”。8 秒延遲后,“游戲結束”顯示在控制臺中。
uj5u.com熱心網友回復:
因為你打電話
Destroy(gameObject);
所以你運行這個協程的物件不再存在 => 該例程執行第一yield條指令的所有內容。
在那之后,它基本上不再存在于引擎中。
您要么需要等待銷毀手榴彈......或者在您的情況下,我會簡單地介紹一個始終存在的例程執行器,例如
public class CoroutineRunner : MonoBehaviour
{
public static CoroutineRunner Instance { get; private set; }
private void Awake()
{
if(Instance && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
}
}
然后做
CoroutineRunner.Instance.StartCoroutine(DelayObjectDestroy(colliders, destroyDelayTime));
但請注意:您仍然不能再訪問任何內置屬性和方法,這需要手榴彈游戲物件仍然存在!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/534922.html
標籤:C#unity3d
