Search Unity

Undo.RegisterCreatedObjectUndo is ridiculously slow

Discussion in 'Immediate Mode GUI (IMGUI)' started by Kayamon, Oct 16, 2018.

  1. Kayamon

    Kayamon

    Joined:
    Sep 5, 2018
    Posts:
    5
    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 :)
     
  2. Kayamon

    Kayamon

    Joined:
    Sep 5, 2018
    Posts:
    5
    Never mind I guess, I restarted Unity and now it's magically fixed itself. o_O

    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?
     
    Last edited: Oct 16, 2018
  3. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    798
    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.
     
  4. Stacklucker

    Stacklucker

    Joined:
    Jan 23, 2015
    Posts:
    82
    exactly the same issue here...
     
  5. Flying_Banana

    Flying_Banana

    Joined:
    Jun 19, 2019
    Posts:
    29
    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:

    Code (CSharp):
    1.  
    2. GameObject clone = Instantiate(...);
    3. clone.hideFlags = HideFlags.HideAndDontSave;
    4. clone.SetActive(false);
    5. Undo.RecordObject(clone, "Insert Tile");
    6. clone.hideFlags = HideFlags.None;
    7. clone.SetActive(true);
    8.  
    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:

    Code (CSharp):
    1.  
    2. GameObject clone = GetTileToDelete(...);
    3. Undo.RecordObject(clone, "Delete Tile");
    4. clone.hideFlags = HideFlags.HideAndDontSave;
    5. clone.SetActive(false);
    6.  
    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 :(
     
    oleg_v, snorlax_buddha and flashframe like this.
  6. MPaluszek

    MPaluszek

    Joined:
    Jan 17, 2019
    Posts:
    20
    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 https://issuetracker.unity3d.com/is...s-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.