Instantiate在Unity中创建多个克隆

Instantiate creates multiple clones in Unity

我有以下代码:

public Rigidbody2D ball;
Vector2 sp = new Vector2(0f, 2.1f);

void Update() {
    if (Input.GetKeyDown("w")) {
        SpawnBall();           
        DestroyBall();
    }
}
void SpawnBall()
{
    Instantiate(ball, sp, transform.rotation);
}

void DestroyBall()
{
    if (ball.transform.position.y >= -5.7f)
    {
        Destroy(ball);
    }
}

并且代码应该在每次按下 "w" 时生成一个新球,但由于某种原因它会创建多个克隆并使引擎崩溃。我怎样才能只创建一个克隆?

而且 destroy 方法也没有做任何事情,尽管它应该在 y 轴上超过 -5.7 时删除克隆。

提前致谢

您的 Destroy() 声明有几个问题。首先,它正在破坏 ball,即 Rigidbody2D。相反,您想要销毁附在球上的游戏对象:
Destroy(ball.gameObject);

其次,您试图在创建球后立即将其销毁,但前提是 y>=-5.7f。我认为相反,您要做的是不断检查球是否高于该点,如果高于则将其摧毁。由于您正在创建多个球,因此它们都需要自己检查,这意味着您需要为球预制件创建一个脚本,并在 Update() 中检查其位置并根据需要销毁(游戏对象)。

我认为您可能还想在脚本开头将 ball 声明为游戏对象,因此您正在实例化游戏对象而不仅仅是 Rigidbody2D:
public GameObject ball;

Object.Instantiate creates a clone of the provided object, so each time it is called a new object is created. MonoBehaviour.Update每帧调用一次,这意味着它每秒至少调用 30 次(在 PC 上通常为 60 次或更多)。

所以每秒 30 次以上,您的代码会检查 w 键是否被按下,如果是:

  • 创建了 ball 的克隆
  • 破坏原来的ball如果y轴超过-5.7

因此,您每秒创建 30 多个球克隆,并且 none 将被删除(因为 DestroyBall 方法只查看原始球,而不查看克隆)。

如果要使用克隆的对象,请将 Instantiate 的结果分配给一个字段:

ballClone = Instantiate(ball, sp, transform.rotation);

然后您可以 check if ballClone exists 并跳过 SpawnBall 调用(如果克隆已存在)。您也可以在 DestroyBall 方法中使用 ballClone

好像是 也很重要。这个答案只是基于查看您的代码和 public Unity 文档;我没有很多 Unity 经验。

创建一个名为 "SpawnRigidbody" 的新脚本并复制并粘贴以下代码。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpawnRigidbody : MonoBehaviour 
{

    public Rigidbody2D ball;
    Vector2 sp = new Vector2(0f, 2.1f);

    void Update() 
    {
        if (Input.GetKeyDown("w")) {
            SpawnBall();
        }
    }

    void SpawnBall()
    {
        Debug.Log ("spawn");
        GameObject go = Instantiate(ball, sp, transform.rotation).gameObject;
        go.AddComponent<DestroyAfterPosition> ();
    }
}

现在创建另一个名为 "DestroyAfterPosition" 的脚本并复制并粘贴以下代码。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DestroyAfterPosition : MonoBehaviour 
{

    void Update ()
    {
        if (transform.position.y <= -5.7f)
        {
            Destroy(gameObject);
        }
    }
}

创建一个空的游戏对象并附加 SpawnRigidbody,然后在检查器中分配你的球。

希望对您有所帮助。

您的销毁调用仅在创建对象后立即被调用一次。

所以它目前正在这样做...

  1. 用户点击按钮...
  2. 创建球...
  3. 检查球是否达到一定高度。不是,所以忽略...
  4. 球会根据重力或任何迫使它下落的力下落。

...并且永远不会被删除。

如果你想让球在到达某个点时被摧毁,要么...

  1. 拥有 SpawnBall return 游戏对象,稍后您可以在更新中存储和检查/删除它,

...或...

  1. 创建一个脚本,只检查对象的 transform.position 并在需要的地方爆炸。将其附加到您正在创建副本的球的预制件上。