实例化 GameObject 会导致所述对象的 Transform 被破坏?

Posted

技术标签:

【中文标题】实例化 GameObject 会导致所述对象的 Transform 被破坏?【英文标题】:Instantiating a GameObject causes said object to have its Transform destroyed? 【发布时间】:2017-05-04 10:41:23 【问题描述】:

Unity 和 C# 新手

这实际上只是我很好奇的一个小问题......我在调整此代码时遇到了它(失败)尝试使其工作。我一直试图让这段代码工作几个小时。

反正这段代码执行的时候,只有一个错误,但是出现了3次。它说“无法销毁'Pillar1'的Transform组件。如果要销毁游戏对象,请改为在游戏对象上调用'Destroy'。不允许销毁转换组件。”

我第一次得到那个。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlatformGenerator : MonoBehaviour 

public GameObject Single;
private GameObject NewPillar;

private int PillarCount;
private bool run;

private int px;
private int py;
private int pz;

void Start () 

    px = 0;
    py = 0;
    pz = 0;

    bool run = true;
    PlatformCreate ();


void Update () 
    if (run) 
        PlatformCreate ();
        if (PillarCount == 3) 
            run = false;
        
    


void PlatformCreate () 
    PillarCount +=1;

    Single.transform.position = new Vector3 (px, py, pz);

    NewPillar = Instantiate (Single, Single.transform);
    NewPillar.name = "Pillar" +PillarCount;

    px += 2;


【问题讨论】:

由于某种原因,它似乎与在实例化中使用 Single.transform 有关...删除并仅使用 Single 不会引发错误,但我仍然想知道为什么。 @Programmer 我投票决定重新提出这个问题,因为绝对没有人打电话给Destroy。请参阅 Ashton 的评论和我在下面的回答。我同意这种类型的大多数问题都是初学者的小错误,但这个问题似乎不同,当然很有趣 @Kay 它必须在 other 脚本的某处被调用。我见过人们发布与他们的问题无关的错误代码。该错误的原因是当您尝试销毁transform 时。例如,Destroy(transform)如果 OP 可以证明不是,我将重新打开。 @programmer,这不会产生预期的结果。还要看看@Ashton 在顶部的评论Single 不会出现错误>他只是想知道为什么? @MukeshSaini Destroy(transform); 主要是导致该错误的原因。我在关闭它之前测试了Instantiate (Single, Single.transform); 并且没有发生错误。我只是再次尝试了大约 15 倍,但出现了错误。这是随机的。它有时会发生。所以,是的,Instantiate (Single, Single.transform); 也会导致这种情况。看起来本地人不理解这一点,并试图在引擎盖下做Destroy(transform)。重新打开。请说出你的答案。 【参考方案1】:

1) 使用以下语句会导致不希望的结果或抛出错误 -

NewPillar = Instantiate (Single, Single.transform);

NewPillar = Instantiate (Single);
NewPillar.transform.parent = Single.transform;

2) 您可以使用以下代码绕过此问题-

NewPillar = Instantiate (Single, Single.transform.position, Single.transform.rotation);

解释: Single 是一个预制件,而不是场景中的实际对象。变换也是一个组件,它确定场景中对象的位置、旋转和比例。根据 Unity3D,由于Single 是一个预制件,因此直接使用它的转换组件被禁用以防止数据损坏。这就是为什么我们在使用上面第 1 点中的语句时会出错的原因。

但我们可以使用存储在预制件的变换组件中的位置、旋转和缩放数据。这让我们可以使用上面第 2 点中的语句。

【讨论】:

OP 没有提到 Single 是一个预制件。但我认为这是原因,因为这是唯一有意义的解释 +1【参考方案2】:

您不能在“转换”类型的引用上调用 Destroy。错误说明您需要将 GameObject 传递给 Destroy 方法,而不是 Transform。

我猜测“破坏”转换的代码部分丢失了,但无论如何,我的猜测是这样的:

    Destroy(transform); // -1

    Destroy(pillar1.transform); //Where pillar1 is a Gameobject -2

    Destroy(pillar1); // Where pillar1 is a Transform -3

替换

-1 有

    Destroy(gameObject);

-2 有

    Destroy(pillar1); //Where pillar1 is a Gameobject -2

-3 与

    Destroy(pillar1.gameObject);

【讨论】:

【参考方案3】:

错误表明已经有一个对象 Pillar1,因此我们假设它是对 PlatformCreate 的后续调用之一。

Instantiate 的调用包括所有孩子。因此,您将Single 克隆为Pillar1,并将新游戏对象重新设置为Single。在下一次调用中,它们都被克隆了。所以Pillar2 将是SinglePillar1

虽然我不明白为什么这不起作用,但我怀疑是内部错误。你确定这是你想要的(也许你只是想指定位置而忘记了旋转(s.Instantiate)?如果这是你想要的,那么尝试将实例化过程分成两个步骤:

    在没有父规范的情况下调用实例化 pillar2.SetParent(Single)

【讨论】:

以上是关于实例化 GameObject 会导致所述对象的 Transform 被破坏?的主要内容,如果未能解决你的问题,请参考以下文章

从映射访问对象会导致新对象 C++ 的实例化

实例化时引用对象

在 Interface Builder 中实例化同一类的多个对象会导致共享属性

GameObject.Instantiate(游戏体的实例化),角色的选择

如何从另一个 GameObject 实例化一个:monobehaviour 脚本

在 Unity 中销毁实例化游戏对象的问题