- Home /
Question by
Arkade · Nov 02, 2013 at 09:23 AM ·
prefabeditor-scriptingundo
How to provide undo for EditorScript changes to a prefab?
I'm writing an Editor Script (or ScriptableWizard) to modify a prefab -- specifically add child GameObjects to the prefab. I wish to make this operation undoable but cannot determine how.
I've tried Undo.RegisterUndo(), Undo.RegisterCreatedObjectUndo() and Undo.SetSnapshotTarget() + Undo.CreateSnapshot() + Undo.RegisterSnapshot().
Here's the code:
[MenuItem("Tools/Add child to prefab", true)]
static bool validateAddChildToPrefab() {
GameObject go = Selection.activeObject as GameObject;
if (null == go) return false;
return PrefabUtility.GetPrefabType(go) == PrefabType.Prefab || PrefabUtility.GetPrefabType(go) == PrefabType.ModelPrefab;
}
[MenuItem("Tools/Add child to prefab")]
static void addChildToPrefab() {
GameObject go = (GameObject) Selection.activeObject;
// register undo -- my question: how to get this to work?
// Undo.RegisterUndo(go, "Add child to prefab"); // does nothing
// makeUndoFor(go, "Add child to prefab"); // (see below) does nothing
// Undo.RegisterCreatedObjectUndo(go, "Add child to prefab"); // error: Undo Created Object may not be performed on persistent or non-default hide flag objects
// Undo.RegisterSceneUndo("Add child to prefab"); // does nothing (not in scene so wasn't hopeful)
GameObject clone = (GameObject) PrefabUtility.InstantiatePrefab(go);
GameObject child = new GameObject("My child");
child.transform.parent = clone.transform;
PrefabUtility.ReplacePrefab(clone, go, ReplacePrefabOptions.ReplaceNameBased);
// Remove the scene instance of the prefab
DestroyImmediate(clone);
}
private static void makeUndoFor(Object root, string actionName) {
Object[] objectsToRecord = EditorUtility.CollectDeepHierarchy(new Object[]{ root });
Debug.Log("Creating UNDO point for "+ objectsToRecord.Length +" objects");
Undo.SetSnapshotTarget(objectsToRecord, actionName);
Undo.CreateSnapshot();
Undo.RegisterSnapshot();
}
p.s. If there's a better way to add child GameObjects to prefabs (i.e. without instantiating), I'd really like to know! Thanks
Comment
Answer by dizzy2003 · Apr 29, 2014 at 06:10 AM
you need to put Undo.RegisterCreateObjectUndo() after the InstantiatePrefab and pass it the new object