Undo.RegisterCreatedObjectUndo is ridiculously slow

So if I try and create say 1000 GameObjects from inside an editor script, it happens almost instantly. Yet if I then add undo entries for them using Undo.RegisterCreatedObjectUndo, it takes several seconds to complete during which time the editor basically freezes.

The profiler reports each call to RegisterCreatedObjectUndo as being around 9ms each time, which therefore for 1000 objects takes 9 seconds total*.* Is this really just how it is or is there some clever way to speed up adding undoes? Not having undo support isn’t an option I’m afraid :slight_smile:

Never mind I guess, I restarted Unity and now it’s magically fixed itself. :eyes:

EDIT: no I take it back, it’s still slow, although it seems to vary depending on random factors. And Undo.DestroyObjectImmediate seems to suffer from the same problem too, although not always at the same time. Any advice?

Long shot… but since this is the only thread I can find about this - did you ever find a solution? Having the same problem and I think I might have to manage the Undo/Redo myself.

exactly the same issue here…

I’ve run into this issue and found somewhat of a solution.

I’m developing a custom 3d Tilemap tool, and supporting undo/redo is a painful process. Undo.RegisterCreatedObjectUndo, Undo.DestroyObjectImmediate are the major bottlenecks.

My solution is to not call these, and fake object creation and deletion. Essentially, when I instantiate a tile prefab, I don’t register its creation with Undo, but I do this:

GameObject clone = Instantiate(...);
clone.hideFlags = HideFlags.HideAndDontSave;
clone.SetActive(false);
Undo.RecordObject(clone, "Insert Tile");
clone.hideFlags = HideFlags.None;
clone.SetActive(true);

Essentially, this tricks Unity Editor into believing that this object has always been there, and when we perform undo, the editor sets the newly created object’s hide flag to hide and don’t save, and deactivate it. When you exit Unity Editor, it won’t be saved to the scene.

Tl;dr, instead of deleting on undo, hide it.

Similar, on deletion, we can do:

GameObject clone = GetTileToDelete(...);
Undo.RecordObject(clone, "Delete Tile");
clone.hideFlags = HideFlags.HideAndDontSave;
clone.SetActive(false);

This will hide it, and it’s gone next time you start Unity.

This dramatically sped up my tool, by about 10x.

Unity should still fix this Undo system though! It’s really hard for tool developers :frowning:

3 Likes

In case someone have the same problem Unity improved Undo a lot in 2021.2.9f1

  • Editor: Optimized calculating the size of Undo operations. Making many changes to GameObjects should now be cheaper to add to the Undo system.

I think this is the issue they fixed Unity Issue Tracker - Pasting, Undoing and Deleting multiple Game Objects in the Scene Hierarchy is non linearly slow
For me it runs 10x times faster in my worst case, from 20+ minutes to 2+ minutes.