void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.layer == layer)
{
StopAllCoroutines();
Destroy(gameObject, 1f);
}
}
//Coroutine is called from another script
public IEnumerator MoveRb(Vector3 destination)
{
yield return new WaitUntil(() => rb.velocity == Vector3.zero);
destination.y = rb.position.y;
rb.velocity = transform.right;
//this is where i get an error
yield return new WaitUntil(() => Vector3.Distance(rb.position, destination) < 0.1f);
rb.velocity = Vector3.zero;
}
基本上,在運行協程時嘗試銷毀物件時得到“MissingReferenceException”。延遲 1 秒,或者用 while 回圈替換“WaitUntil”和“yield return null”都不能解決這個問題。物件被破壞的唯一地方是同一游戲物件腳本內的“OnCollisionEnter”內。我在這里想念什么?
完整的例外訊息:
MissingReferenceException:“剛體”型別的物件已被破壞,但您仍在嘗試訪問它。您的腳本應該檢查它是否為空,或者您不應該銷毀該物件。
uj5u.com熱心網友回復:
正如您在另一個答案上發布的那樣,您實際上是從另一個腳本運行此例程
public class ConveyourBelt : MonoBehaviour
{
void OnCollisionEnter(Collision other)
{
if (other.gameObject.TryGetComponent(out MovingPart movingPart))
{
// runs this Coroutine on THIS component
StartCoroutine(movingPart.MoveRb(transform.position transform.right));
}
}
}
這里的問題是這個ConveyourBelt組件正在運行協程,而不是MovingPart附加到另一個物件的組件
=> 呼叫
StopAllCoroutines();
在MovingPart組件中根本沒有任何效果,因為它從不運行該例程!
因此,當您在 1 秒后銷毀物件時,例程仍可能在ConveyourBelt組件上運行。
作為一種解決方案,您應該讓例程在其他組件上運行,例如
public class ConveyourBelt : MonoBehaviour
{
void OnCollisionEnter(Collision other)
{
if (other.gameObject.TryGetComponent<MovingPart>(out var movingPart))
{
// rather runs the Coroutine on the movingPart component
movingPart.StartCoroutine(movingPart.MoveRb(transform.position transform.right));
}
}
}
uj5u.com熱心網友回復:
你是如何開始你的協程的?也許在你停止了所有的協程之后,你正在創建一個新的協程。
uj5u.com熱心網友回復:
該代碼應該在理論上有效。我認為問題是您試圖在這 1 秒的銷毀延遲期間再次訪問協程。這導致協程在游戲物件被銷毀時運行。
如果你想要這個 1 秒的延遲,那么要么確保在你與某物發生碰撞后不能再次呼叫協程,要么更簡單的方法是讓協程防錯。意味著您在使用之前檢查剛體是否為空。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/424494.html
上一篇:列印時Unicode有不同的寬度
