簡體   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