Instantiate在Unity

时间:2017-07-10 19:41:03

标签: c# unity3d game-physics

我有以下代码:

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时删除克隆。

提前致谢

4 个答案:

答案 0 :(得分:4)

创建一个名为" 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> ();
    }
}

现在创建另一个名为&#34; DestroyAfterPosition&#34;并复制并粘贴以下代码。

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)

您的Destroy()声明存在一些问题。首先,它正在摧毁ball Rigidbody2D。你会想要破坏附在球上的游戏对象:
 Destroy(ball.gameObject);

其次,你试图在创建后立即销毁球,但仅限于y>=-5.7f。我认为相反,你要做的是不断检查球是否高于那个点并且如果是的话就将其摧毁。由于你要创建多个球,他们都需要自己的检查,这意味着你需要为球预制件创建一个脚本,并在Update()检查其位置并根据需要进行Destroy(gameObject)。

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

答案 2 :(得分:1)

Object.Instantiate创建所提供对象的克隆,因此每次调用它时都会创建一个新对象。每帧调用MonoBehaviour.Update,这意味着每秒至少调用30次(通常在PC上调用60次或以上)。

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

  • 创建ball的克隆
  • 如果原始ball在y轴上超过-5.7,则销毁它。

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

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

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

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

ryemoss' answer似乎就是这样  也很重要。这个答案只是基于查看您的代码和公共Unity文档;我没有很多Unity经验。

答案 3 :(得分:0)

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

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

0)用户点击按钮... 1)创造球...... 2)检查球是否有一定的高度。它不是,所以忽略...... 3)球基于重力下降或任何力量迫使它下降。 4)球基于重力或任何用力迫使球不断下降。 5)球在重力或任何力量下都会不断下降。 6)球在重力或任何力量下都会不断下降。 7)球在重力或任何力量下都会不断下降。 8)球在重力或任何力量下都会不断下降。 ......永远不会删除。

如果你想让球在到达某一点时被摧毁,要么...... 1)让SpawnBall返回游戏对象,稍后在Update中存储和检查/删除

...或...

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