簡體   English   中英

在Unity2D中,GameObject被實例化,但是與之碰撞時(有時)不會觸發它應該做的事情

[英]In Unity2D, GameObject gets instantiated but does not trigger what it is supposed to do when collided with (sometimes)

我有一個健康的GameObject,當消滅敵人時有機會實例化它。 在大多數情況下,它可以治愈播放器,播放聲音效果等。換句話說,它可以按照預期的方式運行。 但是,有時(可能是十分之一)進入實例化對象時,它將播放聲音效果,但不會治愈播放器,也不會被破壞。 伴隨的錯誤是:

MissingReferenceException:'GameObject'類型的對象已被破壞,但您仍在嘗試訪問它。 您的腳本應檢查其是否為null或不破壞該對象。 UnityEngine.Object.Internal_InstantiateSingle(UnityEngine.Object數據,Vector3 pos,四元數腐爛)UnityEngine.Object.Instantiate(UnityEngine.Object原始,Vector3位置,四元數旋轉)(在C:/ buildslave / unity / build / Runtime / Export / UnityEngineObject .bindings.cs:211)UnityEngine.Object.Instantiate [GameObject](UnityEngine.GameObject原始,Vector3位置,四元數旋轉)(位於C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.bindings.cs:285) Heart.OnTriggerEnter2D(UnityEngine.Collider2D碰撞)(位於Assets / Scripts / Heart.cs:36)

我一直在試圖弄清楚正在發生什么,而我似乎無法查明問題所在。 在錯誤指向的運行狀況良好對象下(錯誤實際上指向tempPickupEffect實例化的行):

private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.name == "Player_Ship")
    {
        AudioSource.PlayClipAtPoint(receiveSound, Camera.main.transform.position, 0.5f);

        GameObject tempPickupEffect = Instantiate(pickupEffect, transform.position, transform.rotation) as GameObject;
        tempPickupEffect.GetComponent<ParticleSystem>().Play();
        Destroy(tempPickupEffect, 3f);

        heal = true;
        Level1.playerHealth += healAmount;

        Destroy(gameObject);
    }
}

在我的敵人腳本下,當敵人的生命值等於或小於零時,有一個名為spawnHealthUp()的方法被調用。 這是方法:

private void spawnHealthUp()
{
    chance = Random.value;
    if (chance <= healthSpawnChance)
    {
        GameObject copyHealthUp = Instantiate(healthUp, transform.position, Quaternion.identity) as GameObject;
        copyHealthUp.GetComponent<Rigidbody2D>().velocity = new Vector2(-healthSpeed, 0f);
    }
}

在此先感謝您對任何人都可以提供的任何見解。

在您的情況下,可能會發生很多事情,但是我想說您的“ pickupEffect”變量以某種方式無效了,或者由於調用以下命令而發生了這種情況:

tempPickupEffect.GetComponent<ParticleSystem>().Play();

我將在下面詳細介紹這兩種情況。

首先,您可以添加檢查以查看是否未將“ pickupEffect”變量設置為null或某些腳本正在銷毀該GameObject / prefab(通過在其上調用Destroy())。 在調用OnTriggerEnter2D(...)方法內的Instantiate(pickupEffect, ...)之前,請添加此檢查。 這可以通過比較pickupEffect == null==運算符被覆蓋,並將檢查GameObject / prefab是否已被銷毀,按照此答案中的說明 )來完成。

如果對象是被破壞掉了,一個簡單的方法來檢測它被破壞是通過執行以下操作:創建一個包含一個小腳本OnDisable()函數,並添加Debug.Log()與它的任何文本調用。 Debug.Log()調用將記錄您的文本,還將在日志消息中添加堆棧跟蹤 ,您可以使用該跟蹤來驗證對Destroy()函數的調用在何處進行(從而發現GameObject的位置)被摧毀)。

// This script should be added to the "pickupEffect" gameobject
void OnDisable()
{
    Debug.Log("Object destroyed!");
}

當te對象被銷毀時,將生成類似於以下內容的輸出:

Object destroyed!
UnityEngine.Debug:Log(Object)
MyObjectBeingDeleted:OnDisable() (at
Assets/MyObjectBeingDeleted.cs:10) UnityEngine.Object:Destroy(Object)
MyDestroyerObject:Update() (at Assets/MyDestroyerObject.cs:11)

上面的堆棧跟蹤告訴我,在MyDestroyerObject.cs腳本的第11行上已調用Destroy()方法。


另一方面,問題可能出在代碼的這一部分:

tempPickupEffect.GetComponent<ParticleSystem>().Play();
Destroy(tempPickupEffect, 3f);

在這里,您要命令“粒子系統”進行播放,但是在發出該命令之后,您將銷毀包含該“粒子系統”的GameObject。 這實際上是一種不好的做法(並且最終可能會導致難以調試的異常)。 我建議您使用Update()方法創建一個腳本,該腳本檢查粒子系統是否已結束其執行,並在執行結束后銷毀該對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM