- Home /
Why do I get an empty Undo for my EditorWindow?
Hi There
I have Undo/Redo working for my EditorWindow, but the very first thing I undo appears to be nothing, i.e. an Empty Undo. I'll detail the scenario below, all help appreciated.
I have a node based EditorWindow or my Behaviour Tree implementation. When one of my nodes is moved I record the rect on the node class (serialisable) which is part of a hierarchy on a ScriptableObject. In OnGUI I also detect whether a node is added or deleted and I detect GUI changes as well as seems to be the case for the example code from the help.
So in On GUI I have something like:
void OnGUI()
{ // get the selection
BVTreeDescription tree = Selection.activeObject as BVTreeDescription;
if(tree == null)
{ // clear tree
m_tree = null;
return;
}
// use this tree
m_tree = tree;
// we want to update on scene change
autoRepaintOnSceneChange = true;
// handle undo
Undo.SetSnapshotTarget(m_tree, "Editing Behaviour Tree");
// no rects changed yet, or nodes added
m_nodes_changed = false;
m_rect_changed = false;
// *** The GUI is rendered here but it's a lot of code so I've cut it! ***
// the behaviour tree view
m_scroll_pos = GUI.BeginScrollView(scroll_area, m_scroll_pos, m_required_area);
// behaviour tree nodes
BeginWindows();
RenderNode(m_tree.Root, null); // will render all children as well
EndWindows();
// end view
GUI.EndScrollView();
// save asset if edited!
if(GUI.changed || m_nodes_changed || m_rect_changed)
{ // dirty!
EditorUtility.SetDirty(m_tree);
// and save the snapshot
Undo.CreateSnapshot();
Undo.RegisterSnapshot();
// force a repaint - I maybe need this if the nodes changed?
Repaint();
}
else
{
Undo.ClearSnapshotTarget(); // totally unsure whether this is doing anything!
}
}
So I've cut the guts of the code because it's quite a lot and probably not relecant, but basically does my Undo logic look broadly right? FYI, each node is rendered using GUILayout.Window(). And for reference looks broadly like this:
it all works other than I just get an empty undo at the very end, so the first thing I undo changes nothing, but the next undo is the first expected undo. Weirdly, if I just drag a window and then undo, the first undo DOES undo the window's rect position. If however, I change the node type from say Action to Condition, then the first undo is empty. I've added logging in the if clause at the end and it's only being called once it seems and I've tried moving the actual to its own if clause, more in line with the example from docs, but in that case when I change the node type this does not get undone (so setting an asset to dirty does not give you free undo for an EditorWindow).
I feel something isn't quite right but I can't see where I might be going wrong. Has anyone else come across this issue?
Again, all help appreciated! Bovine
Hmmmm... I moved the call to Undo.CreateSnapshot() after the SetSnapshotTarget() and it all works fine. Should it? This is NOT what the documentation example is doing :o/
Your answer
Follow this Question
Related Questions
Editing and Undo for non-unity properties 2 Answers
How do you undo operations from an EditorWindow? 1 Answer
Undo problems with a Custom EditorWindow 0 Answers
Undo issues in EditorWindow 0 Answers
Repaint on Undo 5 Answers