C# 如何更改通过PrefableUtility.InstancePrefab实例化的游戏对象的父对象?

C# 如何更改通过PrefableUtility.InstancePrefab实例化的游戏对象的父对象?,c#,unity3d,C#,Unity3d,通常,您会在脚本中使用 var obj = (GameObject)Instantiate(....); 而不是使用 var obj.transform.SetParent(...); 不过,我正在编写一个小的编辑器脚本,用于在菜单项上实例化预置,该菜单项应保持它们与预置的链接。我在一个静态的类中这样做: public static class EditorMenu { // This is a reference that I already have and is not nul

通常,您会在脚本中使用

var obj = (GameObject)Instantiate(....);
而不是使用

var obj.transform.SetParent(...);
不过,我正在编写一个小的编辑器脚本,用于在菜单项上实例化预置,该菜单项应保持它们与预置的链接。我在一个
静态的
类中这样做:

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:SetParent(Transform)

prefact
obj
是prefact的最高
GameObject
,因此我认为我设置的是整个实例化对象的父对象,而不是prefact层次结构中的任何变换

如何更改通过实例化的
游戏对象的父对象


更新

我刚才尝试的一个工作就是实际使用
实例化
并执行

var obj = Object.Instantiate(prefab, cancel.transform);

// remove the added "(clone)" suffix
obj.name = prefab.name;
obj.transform.SetParent(cancel.transform);
但是,如前所述,这并不能完全保持prefb功能的完整性。。因此,它只允许我
还原
,但
应用
更改。作为解决方法,它可能已经足够好了,但是因为在我的例子中,我使用它作为实例化预设的快捷方式,用户以后不应该真正更改它

如何更改通过PrefableUtility.InstancePrefab实例化的游戏对象的父对象

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

obj.transform.parent = cancel.transform;

抱歉,我刚刚发现问题:

我没有添加它,因为错误消息令人困惑/错误

我正在使用检查类型为
SomeType
exampleParent
是否在场景中

下面是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;
}
但是这似乎实际上是错误的,而且不起作用,因为它总是从预置中返回
SomeType
引用!(我已经觉得他们这样做有点奇怪了

!EditorUtility.IsPersistent(target.transform.root.gameObject))
    continue;
我不确定这是否是他们示例代码中的一种类型


因此,这个听起来像设置父项是不允许的错误实际上意味着并且应该说

不允许将父级设置为驻留在预置中的变换

而不是我一开始就发现了真正的问题



因此,再次作为一种解决方法,直到我能够找出我切换到
对象的
FindObjectsOfTypeAll
对象。FindObjectOfType
而不是假设我的目标在场景中始终处于活动状态。并且使用
SetParent
prefautility一起工作。InstancePrefab

您确定
Instantiate()
只能从MonoBehavior调用?这是一个静态调用
游戏对象。实例化()
@z3nth10n否我刚刚更新了该部分;)实际上我又试了一次,但它与使用
实例化prefab
不同,因为
实例化
阻止了诸如
应用
更改之类的预设功能。我发现了问题,看到错误消息的格式不正确,实际问题在于我没有提供的代码,所以我投票结束了这个问题。如前所述这就是我正在做的,但是它抛出
设置驻留在预置中的转换的父级被禁用,以防止数据损坏。UnityEngine.Transform:SetParent(Transform)
您使用的是哪个版本的Unity,以及如何获得cancel对象?2017.4.18。但我发现了问题所在。实际上,这就是我得到父变换的方式。。错误信息真的很糟糕。看见不管怎样,我还是投票支持你,因为基本上你是对的;)