代码之家  ›  专栏  ›  技术社区  ›  derHugo

如何更改通过prematability.instantiateprob实例化的游戏对象的父对象?

  •  3
  • derHugo  · 技术社区  · 6 年前

    通常,在脚本中使用

    var obj = (GameObject)Instantiate(....);
    

    而不是改变它的父母

    var obj.transform.SetParent(...);
    

    不过,我正在编写一个小编辑器脚本,用于在菜单项上实例化前言,这些菜单项应该保持与前言的链接。我做的是 static 类:

    public static class EditorMenu
    {
        // This is a reference that I already have and is not null
        privtae static Transform exampleParent;
    
        [MenuItem("Example/Create Clone")]
        private static void CreateClone()
        {
            var prefab = AssetDatabase.LoadAssetAtPath("Example/Path/myObject.prefab", typeof(GameObject));
            var obj = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
    
            obj.transform.position = Vector3.zero;
            obj.transform.rotation = Quaternion.identity;
    
            Selection.activeGameObject = obj;
        }
    }
    

    我不得不使用

    (GameObject)PrefabUtility.InstantiatePrefab(prefab);
    

    因为 Instantiate() 不保留到预设的链接,而是创建一个克隆。

    所以到目前为止,上面的代码工作得很好,对象被插入到场景中,就好像我要拖放它一样。

    现在,我想将这个新实例化的对象父级更改为 parent 所以我加了一行

    obj.transform.SetParent(exampleParent, true);
    

    我也尝试过

    obj.transform.parent = exampleParent;
    

    但两者都有例外:

    禁用设置位于预置中的转换的父级以防止数据损坏。 UnityEngine.Transform:设置父级(转换)

    prefab 从而 obj 是最顶层的 GameObject 因此,我认为我正在设置整个实例化对象的父对象,而不是预制层次结构内部的任何转换。

    如何更改 游戏对象 通过实例化 PrefabUtility.InstantiatePrefab ?


    更新

    我刚试过的一个工具是 Instantiate 并且做

    var obj = Object.Instantiate(prefab, cancel.transform);
    
    // remove the added "(clone)" suffix
    obj.name = prefab.name;
    obj.transform.SetParent(cancel.transform);
    

    但是,正如前面提到的,这并不能完全保持prefb功能的完整性。所以它只允许我 Revert 但是 Apply 变化。但是,作为解决方法,它可能已经足够好了,因为在我的例子中,我使用它作为一个快捷方式来实例化一个用户以后不应该真正更改的预制件…

    2 回复  |  直到 6 年前
        1
  •  1
  •   shingo    6 年前

    如何更改通过prematability.instantiateprob实例化的游戏对象的父对象?

    这是对的,但要确保 取消 也是一个 实例化 对象。

    obj.transform.parent = cancel.transform;
    
        2
  •  1
  •   derHugo    6 年前

    抱歉,我刚发现问题:

    我没有添加它,因为错误消息的格式很混乱/不正确。

    我在用 Resources.FindObjectsOfTypeAll 用于检查 exampleParent 类型的 SomeType 在现场。

    以Unity为例 应排除 我使用的预制件

    // Validation for the Menu item
    [MenuItem("Example/Create Clone", true]
    private bool TargetAvailable()
    {
        foreach (var target in (SomeType[])Resources.FindObjectsOfTypeAll(typeof(SomeType))
        { 
            if (target.hideFlags == HideFlags.NotEditable || target.hideFlags == HideFlags.HideAndDontSave)
                continue;
    
            if (!EditorUtility.IsPersistent(target.transform.root.gameObject))
                continue;
    
            exampleParent = target.transform;
            return true;
        }
    
        exampleParent = null;
        return false;
    }
    

    但是 这似乎是错误的,而且不起作用,因为它总是让我 基类型 引自前言!(我已经觉得他们这样做有点奇怪了

    !EditorUtility.IsPersistent(target.transform.root.gameObject))
        continue;
    

    我不确定那是不是 ! 可能是他们示例代码中的一个类型?!


    所以,这个听起来像是设置父对象的错误实际上意味着并且应该说

    设置父级 不允许存在于预设中的转换…

    比我一开始就发现的实际问题还要多。


    所以作为一个解决方法,直到我能明白 FindObjectsOfTypeAll 我切换到的东西 Object.FindObjectOfType 相反,假设我的目标总是活跃在现场。并使用 SetParent 现在与一起工作 PrefabUtitlity.InstantiatePrefab .