var obj = (GameObject)Instantiate(....);
然后使用以下方法更改其父元素:
var obj.transform.SetParent(...);
我正在编写一个小的编辑器脚本,用于在菜单项上实例化prefabs并保持它们与prefab之间的链接。我将其放在一个静态
类中,如下所示:
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)
prefab
和通过它实例化的 obj
都是预制件的最上层 GameObject
,因此我认为我正在设置整个实例化对象的父项,而不是任何预制件层次结构内的变换。
如何更改通过PrefabUtility.InstantiatePrefab
实例化的 GameObject
的父项?
更新
我刚刚尝试的一个解决方法是实际使用Instantiate
并执行以下操作:
var obj = Object.Instantiate(prefab, cancel.transform);
// remove the added "(clone)" suffix
obj.name = prefab.name;
obj.transform.SetParent(cancel.transform);
然而,正如之前提到的那样,这并不能完全保持prefb功能的完整性...因此,它只允许我还原
,但不允许应用
更改。作为解决方法,这可能已经足够了,因为在我的情况下,我将其用作实例化预制件的快捷方式,用户后来不会真正想要更改...
Instantiate()
只能从 MonoBehaviour 调用吗?这是一个静态调用GameObject.Instantiate()
。 - z3nth10nInstantiatePrefab
不同,因为Instantiate
会破坏预制件的功能,例如Apply
更改。 - derHugo