【问题标题】:How to destroy child object when parent is destroyed?父对象被销毁时如何销毁子对象?
【发布时间】:2017-09-01 23:12:16
【问题描述】:

我正在 Unity 5 中制作一个 2D 游戏,其中玩家拥有一把对玩家来说是孩子的枪,当玩家被击中时我如何摧毁枪?我正在使用的当前代码会破坏播放器,但不会破坏枪。

public float health=500f;
public GameObject gun;

void OnTriggerEnter2D(Collider2D collider){
    BulletScript bullet = collider.gameObject.GetComponent<BulletScript> ();

    if (bullet) {
        health -= bullet.getdamage ();
        bullet.hit ();
        Handheld.Vibrate();

        if (health <= 0) {
            GetComponent<Animator> ().SetBool ("deadBool", true);
            GetComponent<Animator> ().SetTrigger ("deadTrigger");
            ExecuteAfterTime (1f);
            Destroy (gun);
        }
    }

}
IEnumerator ExecuteAfterTime(float time){
    yield return new WaitForSeconds (time);
    Destroy (gameObject);
    GameObject child = gameObject.GetComponentInChildren<> (gameObject);
}

注意:枪是应用脚本的玩家的孩子。

【问题讨论】:

  • 我假设当不再存在对它的引用时,它会自动进行垃圾收集。因此,当您的玩家死亡时,参考计数器会减一。如果你没有更多关于那把枪的参考资料,它很快就会被扔掉。无论如何:为什么不打电话给Destroy(child)
  • 子对象应该在其父对象被销毁时自动销毁。请用 GameObject 和一个孩子做一个简单的测试,然后摧毁父母。孩子也该走了。
  • 这把枪必须是层级视图中玩家的子级才能被销毁。

标签: c# unity3d unity5


【解决方案1】:

如果您只想销毁枪支,那么我会说在脚本中保留您的枪支参考,如下所示:

public GameObject gun;

从检查员那里分配枪。然后像这样被击中时摧毁它:

Destroy(gun);

如果您在 player 下有多个孩子。然后你可以像这样创建一个数组:

public GameObject[] destroyables;

从检查器分配它并保存预制件。然后在命中时使用循环销毁。

for(int i=0;i<destroyables.Length;i++) Destroy(destroyables[i]);

【讨论】:

  • 我按照你说的做了修改,我的枪也被摧毁了,但唯一的问题是枪在玩家被摧毁之前就被摧毁了,延迟很尴尬。(我已经更新了代码)跨度>
  • 你想什么时候毁掉这把枪?玩家被摧毁后还是与玩家一起?
  • 与播放器
  • 你可以在销毁任何东西之前尝试 SetActive(false) 确保它按照你喜欢的顺序消失。
  • @Varun 呼叫销毁(枪);行前 Destroy (gameObject);
【解决方案2】:

假设您要销毁每个孩子,您可以首先检索所有孩子:

allChildren  = gameObject.getComponentsInChildren()

这将产生一个数组,因此您可以简单地使用如下循环遍历它们:

for (int a = 0; a < allChildren.length; aa ++)
{
    Destroy(allChildren[a].gameObject);
}

如果枪是您想要在该循环内销毁的唯一孩子,您可以查询有关该对象的详细信息并在找到枪时调用 Destroy,例如:

if(allChildren[a].name == "gun")
{
    Destroy(allChildren[a].gameObject)
}

【讨论】:

    【解决方案3】:

    当你销毁父游戏对象时,所有子对象都会自动销毁。但是您尝试手动销毁所有这些。 你有延迟,因为你在协程中调用 Destory(gameObject) 。尝试将 Destroy(gun) 也移到协程中。

    public float health=500f;
    public GameObject gun;
    
    void OnTriggerEnter2D(Collider2D collider){
    BulletScript bullet = collider.gameObject.GetComponent<BulletScript> ();
    
        if (bullet) {
            health -= bullet.getdamage ();
            bullet.hit ();
            Handheld.Vibrate();
    
            if (health <= 0) {
                GetComponent<Animator> ().SetBool ("deadBool", true);
                GetComponent<Animator> ().SetTrigger ("deadTrigger");
                StartCoroutine(ExecuteAfterTime (1f));             
            }
        }
    
    }
    IEnumerator ExecuteAfterTime(float time){
        yield return new WaitForSeconds (time);
    
        //destroying gun only
        Destroy (gun);
    
        //manually destroying all of childre
        GameObject child = gameObject.GetComponentInChildren<> (gameObject);
        foreach(var entry in child )
        {
            Destroy(entry);
        }
    
        Destroy (gameObject);
    
    }
    

    【讨论】:

    • 使用毁灭(枪);在 ExecuteAfterTime() 方法不起作用。它不会破坏枪支。
    • 您可以将 ExecuteAfterTime() 与 StartCoroutine() 一起使用。我正在编辑答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    相关资源
    最近更新 更多