Unity3D - 在销毁对象后无法重新生成对象

时间:2014-09-25 01:44:09

标签: c# unity3d

我有一个问题,在预制件被销毁后重新生成预制件。经过一秒钟的摧毁,我似乎无法让它重新回到原来的起始位置。我创建了一个空的游戏对象并将SpawnTargets.cs脚本附加到它。我不确定应对这种情况的最佳方法。附加脚本的另一个对象实际上是对预制件的破坏。 BulletCollisionHandler.cs工作正常。谢谢你的帮助。代码如下:

SpawnTargets.cs:

using UnityEngine;
using System.Collections;

public class SpawnTargets : MonoBehaviour 
{
    public GameObject targetCircle;
    public GameObject targetSquare;
    public GameObject targetStar;

    private Vector3 circleSpawnPosition = new Vector3(0.0f, 1.227389f, -7.5f);
    private Vector3 squareSpawnPosition = new Vector3(0.0f, 1.027975f, -7.993299f);
    private Vector3 starSpawnPosition = new Vector3(0.0f, 1.8f, -7f);

    // Use this for initialization
    void Start ()
    {

    }

    // Update is called once per frame
    void Update ()
    {
        SpawnTarget ();
    }

    void SpawnTarget()
    {

    }
}

BulletCollisionHandler.cs:

using UnityEngine;
using System.Collections;

public class BulletCollisionHandler : MonoBehaviour 
{
    public GameObject targetCircle;

    // Use this for initialization
    void Start () 
    {
        Destroy (gameObject, 2);
    }

    // Update is called once per frame
    void Update ()
    {

    }

    void OnCollisionEnter(Collision other)
    {
        if(other.gameObject.name == "TargetSquare")
        {
            other.gameObject.rigidbody.isKinematic = false;
            ((TargetMovementHorizontal)other.gameObject.GetComponent<TargetMovementHorizontal>()).enabled = false;

            Destroy (other.gameObject, 1);
            Debug.Log("Hit square");
        }
        else if(other.gameObject.name == "TargetCircle")
        {
            other.gameObject.rigidbody.isKinematic = false;
            ((TargetMovementHorizontal)other.gameObject.GetComponent<TargetMovementHorizontal>()).enabled = false;

            Destroy (other.gameObject, 1);

            Debug.Log("Hit circle");
        }
        else if(other.gameObject.name == "TargetStar")
        {
            other.gameObject.rigidbody.isKinematic = false;
            ((TargetMovementHorizontal)other.gameObject.GetComponent<TargetMovementHorizontal>()).enabled = false;
            ((TargetMovementVertical)other.gameObject.GetComponent<TargetMovementVertical>()).enabled = false;

            Destroy (other.gameObject, 1);
            Debug.Log("Hit star");
        }
    }
}

2 个答案:

答案 0 :(得分:1)

你没有在任何地方调用Instantiate(),因此很难看到你提供的代码中新对象的来源。

无论如何,最好不要使用Destroy。如果您想立即重置对象,为什么不简单地将其回收到起始位置?避免实例化和销毁大量对象是个好主意,最好隐藏/禁用不需要的对象并取消隐藏/重新启用它们。

这里是a tutorial on the general idea.本教程是关于对象组的,但同样的技巧也适用于回收单个对象。

答案 1 :(得分:0)

你最好使用gameObject.SetActive(true / false);用于激活/停用gameObject而不是仅仅使用Destroy。

然后,如果你正在使用Destroy,你会想到3个选项,让它在玩家看到之前进入欲望的位置。

1)在禁用其渲染器组件后启用游戏对象。然后你将变换的位置/旋转均衡到你需要的位置/旋转。之后,重新启用Renderer组件。它应该放在你想要的地方。

2)您实例化gameObject,但首先确保默认情况下在其预制件上禁用渲染器组件,以便您可以重新分配其Transform值,然后再次重新启用渲染器。

3)你创建一个不可见的gameObject(一个空游戏对象)并实例化想要的gameObject,然后让Empty成为新创建的gameObject的父级。假设父空是你想要它的确切位置,当你实例化并重置孩子的位置时,它应该从空父母的顶部跳出来。

我没有提供代码,因为你还没有,我也不知道你最喜欢哪种方法。在性能方面,启用/禁用是最佳选择。

正如正统人所说,对象池是你最好的朋友,比如子弹,尽管它可能适用于许多其他可能作为对象收集的游戏对象&#39;在你的游戏逻辑上。这完全值得学习。