繁体   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