繁体   English   中英

Unity3D-销毁对象后无法重生

[英]Unity3D - unable to respawn an object after it has been destroyed

销毁预制件后,重新生成预制件时出现问题。 一秒钟被摧毁后,我似乎无法让它重新恢复其原始开始位置。 我创建了一个空的游戏对象,并将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");
        }
    }
}

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

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

这是有关一般概念的教程。 本教程是关于对象组的,但是相同的技巧也可以用于回收单个对象。

您最好使用gameObject.SetActive(true / false); 用于激活/停用游戏对象,而不仅仅是使用Destroy。

然后,如果您使用的是“销毁”,那么您会想到3种选择,以便在播放器看到之前将其置于所需位置。

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

2)您实例化gameObject,但首先要确保默认情况下在其Prefab上禁用了Renderer组件,因此您可以重新分配其Transform值,然后-再次重新启用Renderer。

3)创建一个不可见的gameObject(一个Empty游戏对象)并实例化所需的gameObject,然后使Empty成为新创建的gameObject的父对象。只要父Empty恰好位于您想要的位置,当您实例化并重置孩子的位置,它应该在Empty父对象的顶部跳出。

我没有给出代码,因为您没有,而且我也不知道您最终会喜欢哪种方法。 就性能而言,启用/禁用是最佳选择。

正如theodox所说,“对象池化”是子弹之类的最好朋友,尽管它可能会应用于许多其他游戏对象,这些对象可能会在游戏逻辑上充当“对象的集合”。 完全值得学习。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM