我有一个健康的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);
}
}
在此先感谢您对任何人都可以提供的任何见解。
答案 0 :(得分:0)
在您的情况下,可能会发生很多事情,但是我想说您的“ pickupEffect”变量由于某种原因而失效了,或者发生这种情况是由于调用:
tempPickupEffect.GetComponent<ParticleSystem>().Play();
我将在下面详细介绍这两种情况。
首先,您可以添加检查以查看是否未将“ pickupEffect”变量设置为null或某些脚本正在销毁该GameObject / prefab(通过在其上调用Destroy())。立即在您的Instantiate(pickupEffect, ...)
方法内调用OnTriggerEnter2D(...)
之前添加此检查。可以通过比较pickupEffect == null
(==
运算符被覆盖,并根据this answer的含义检查GameObject / prefab是否已销毁)来完成此操作。
如果对象被破坏,则通过执行以下操作来检测被破坏的位置的简单方法:创建一个包含OnDisable()
函数的小脚本,并添加一个{ {1}}呼叫并带有任何文字。 Debug.Log()
调用将记录您的文本,还将在日志消息中添加堆栈跟踪,您可以用来验证对Debug.Log()
函数的调用在哪里(从而发现您的GameObject被销毁的位置)。
Destroy()
当te对象被破坏时,将生成类似于以下内容的输出:
// This script should be added to the "pickupEffect" gameobject
void OnDisable()
{
Debug.Log("Object destroyed!");
}
上面的堆栈跟踪告诉我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()
在这里,您要命令“粒子系统”玩游戏,但是在发出该命令之后,您将销毁包含该“粒子系统”的GameObject。这实际上是一种不好的做法(并且最终可能会导致难以调试的异常)。我建议您使用tempPickupEffect.GetComponent<ParticleSystem>().Play();
Destroy(tempPickupEffect, 3f);
方法创建一个脚本,该脚本检查粒子系统是否已结束其执行,并在执行结束后销毁该对象。