Unity给一个Prefab添加子物体报错Setting the parent of a transform which resides in a Prefab Asset is disabled t

今天在写一个批量修改预制体的Editor脚本,在写给一个预制体添加子物体时,出现了Setting the parent of a transform which resides in a Prefab Asset is disabled to prevent data corruption的报错。
具体报错代码简化后如下:

	 GameObject parentPrefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Editor/Prefabs/parent.prefab");
	 GameObject childPrefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Editor/Prefabs/child.prefab");
	 childPrefab.transform.parent = parentPrefab.transform;
	 PrefabUtility.SavePrefabAsset(parentPrefab);

查找资料时,很快找到原因,给没有实例化的Prefab添加父物体的时候就会出现此报错。于是把代码修改为:

	GameObject childPrefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Editor/Prefabs/child.prefab");
	GameObject child = Instantiate(childPrefab);
	child.transform.parent = parentPrefab.transform;

把子物体的prefab实例化了,加断点调试发现child.transform.parent的值也有成功设置到,但是还是报同样的错。后来在一回答里发现了问题所在,https://stackoverflow.com/questions/46063784/unity-error-setting-the-parent-of-a-transform-which-resides-in-a-prefab-is-disa
在这里插入图片描述
即父物体也要经过实例化,我们无法对未实例化的Prefab的transform进行任何修改。那就把父物体也进行实例化吧。

        GameObject parentPrefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Editor/Prefabs/parent.prefab");
        GameObject parent = Instantiate(parentPrefab);
        GameObject childPrefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Editor/Prefabs/child.prefab");
        GameObject child = Instantiate(childPrefab);
        child.transform.parent = parent.transform;

这时候,我们成功把一个子物体实例添加为父物体实例的子物体。因为我初衷是批量修改父物体prefab,那如何保存父物体实例呢?直接保存会报错:ArgumentException: Can’t save a Prefab instance。
参考 https://blog.csdn.net/iningwei/article/details/88354534,用PrefabUtility.SaveAsPrefabAsset(17前的版本可以用PrefabUtility.ReplacePrefab)方法保存修改,成功。完事后别忘了把parent实例给删除掉,不然仍会存在与当前场景中。
完整代码如下:

    [MenuItem("Test/test")]
    static void test1()
    {
        GameObject parentPrefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Editor/Prefabs/parent.prefab");
        GameObject parent = Instantiate(parentPrefab);
        GameObject childPrefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Editor/Prefabs/child.prefab");
        GameObject child = Instantiate(childPrefab);
        child.transform.parent = parent.transform;
        PrefabUtility.SaveAsPrefabAsset(parent, "Assets/Editor/Prefabs/parent.prefab");
        DestroyImmediate(parent);
    }

由于不太熟悉写预制体的操作,花了比较多的时间。也没有找到比较详细的资料,所以把我解决过程整理一下,希望能帮到有需要的朋友~

你可能感兴趣的:(Unity,unity)