【问题标题】:Unity3d Instantiate a child prefab from the parent sourceUnity3d 从父源实例化一个子预制件
【发布时间】:2014-09-14 07:56:17
【问题描述】:

我最初在 answers.unity3d 上发布了这个问题,但没有得到任何答案 Unity3d Instantiate a child prefab from the parent source

我有一个名为 GreyPiece 的预制件,当点击它时,这个 GreyPiece 应该会创建相同类型的子代 目前我的 GreyPiece 类有一个名为 GreyPieceTransform 的公共 Transform 对象

public Transform greyPieceTransform;

这个Transform与主要的GreyPiece Prefab相同[在Unity3d编辑器中拖放] 当点击对象时,我[根据需要]为此对象实例化多个子对象并将转换设置为父对象

Transform greyPiece = Instantiate(greyPieceTransform, transform.position, transform.rotation) as Transform;
greyPiece.parent = transform;
Debug.Log("this id "+transform.GetInstanceID()+"\tprefab id "+greyPieceTransform.GetInstanceID()+"\tchild id "+greyPiece.GetInstanceID());

到目前为止一切顺利,如果我创建一个对象并单击它,我将有 1 个孩子

  • 父级
    • 孩子

现在如果我创建 2 我会得到这个

  • 父级
    • 孩子
    • 孩子
      • 孩子

如果我创建 3

  • 父级
    • 孩子
    • 孩子
      • 孩子
    • 孩子
      • 孩子
      • 孩子
        • 孩子

基本上发生的事情是原始的 GreyPieceTransform 似乎正在发生变化,当我尝试实例化另一个对象时,它会采用修改后的 [当前父级] 并从中实例化 如果我没有设置新实例化对象的父级,则不会发生此问题

编辑:我还添加了调试输出 debug.Log 输出是这样的

这个 id -185148 prefab id -185148 子 id -185236

此 id -185148 prefab id -185148 子 id -185318

此 id -185148 预制件 id -185148 子 id -185418

如您所见,父变换和预制变换具有相同的 id,但它们不应该

为了更清楚,我决定将变换命名为“灰色”+greyPiece.getInstanceID(); 这就是它在层次视图中的外观

那么现在,我怎样才能让 grePieceTransform 实际引用预制件 [从预制件中实例化] 而不是它与父代具有相同的引用

【问题讨论】:

  • 我猜 grayPieceTransform 指向的是预制件实例而不是预制件本身,不是吗?
  • @Heisenbug 显然正在发生的事情是,当从预制变换 [greyPieceTransform] 实例化一个对象时,它使用它作为当前对象并修改原始对象 [所以 grayPiece 和 grayPieceTransform 将是相同的],我不确定如何防止这种情况发生>_
  • 我不明白您要为公共字段 grayPieceTransform 分配什么。您是否有一个脚本实例,其中 grayPieceTransform 字段指向预制件(在项目中)?我想不会,否则它会按预期工作。你可能有一个对象的实例,它的变换与 grayPieceTransform 相同(检查实例 ID)。
  • @Heisenbug 公共字段 grayPieceTransform 在 Unity3d 编辑器中分配 [拖放] 用于预制件,我会检查他们的 id 并回复你,感谢 id 的想法!

标签: c# unity3d parent-child instantiation


【解决方案1】:

我猜问题如下。在第一次实例化时,transformgreyPieceTransform 指向同一个对象。 您可以查看comparing instance ids

如果是这种情况,您看到的行为是合理的。第一次实例化一个新的GameObject 时,源对象没有父对象也没有子对象,所以你只有一个子对象。第二次用 1 个子实例实例化父级并将其附加为子级(图 2)。 以此类推。

这里有一个简单的 sn-p 可能会有所帮助:

public class Test : MonoBehaviour {

    public Transform prefab;

    // Use this for initialization
    void Start () {

    }

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

        if (Input.GetKeyDown(KeyCode.A))
        {
            Debug.Log("prefab id " + prefab.GetInstanceID() + " this id " + transform.GetInstanceID());
        }
    }
}

它将根据对象引用的设置方式打印不同的 id 组合。

案例 1

如果Test 附加到hierarchy 中的对象并且prefab 是对项目中预制件的引用,则id 将不同

案例 2

如果Test 附加到hierarchy 中的对象(这是一个预制件实例)并且prefab 是对项目ID 中链接预制件的引用,仍然会有所不同。 (预制件是从实例化对象到预制件的链接。在这种情况下,它应该是预制件属性覆盖,您应该在检查器中看到粗体字)。ID 会有所不同。

案例 3

如果Test被附加到一个prefab并且prefab字段指向自身,当它第一次实例化(或拖入层次结构)时,transform和prefab字段将指向同一个对象(预制实例)。 ID 将相等。

显然发生的事情是在实例化一个对象时 来自预制转换 [greyPieceTransform],它使用它作为 当前对象并修改原始对象[所以 grayPiece 和 grayPieceTransform 是一样的]

没有。如果对象的greyPieceTransformtransform 不同,则不会修改“原始”。但可能他们不是。

【讨论】:

  • 你是对的,ID 是相同的 [我用更多信息编辑了问题],现在我不确定在创建它的子节点时如何引用主预制件.. 有什么想法吗?
  • 要获得适当的建议,我需要知道具体的用例场景(但可能值得另一个专门的问题)。我想你不能这样做你正在尝试这种方式。可能最简单的解决方案是分担责任。实例化和维护层次链的对象存储为预制件。实例化另一个子对象的对象是另一个对象(最终存储为另一个预制件)。
  • 哦,我等着看别人能不能找到,如果没有,我会接受你的回答并发布另一个问题
猜你喜欢
  • 1970-01-01
  • 2014-05-27
  • 1970-01-01
  • 1970-01-01
  • 2018-07-28
  • 2020-01-01
  • 1970-01-01
  • 2021-03-08
  • 1970-01-01
相关资源
最近更新 更多