Undo Collapse into group not applying to Redo operation
Hey Everyone,
I have some code for a tree structure that creates a node and makes some Undo operations, then collapses them into one group. The undo works just fine, but trying to then redo only performs the last operation not the entire Undo group or sometimes nothing at all. Is this designed intentionally or am I missing something within the Undo class?
For example, after performing an Undo from the Editor, the node is correctly removed but the redo operation is only an "Add Component" and not the parent object "Add Child" so after a redo the node exists but the parent doesn't know about it...
public T addNode<T>(ParentNode parent, string name) where T : class, new() {
Undo.SetCurrentGroupName("Add Node");
int group = Undo.GetCurrentGroup();
TreeNode node = (TreeNode) Undo.AddComponent(gameObject, typeof(T));
node.parent = parent;
node.NodeName = name;
node.TreeDataDict = treeDataDict;
node.hideFlags = HideFlags.HideInInspector;
Undo.RecordObject(parent, "Add Child");
parent.addChild(node); //adds node to a Serialized List<TreeNode>
Undo.RecordObject(this, "Check Depth");
int nodeDepth = depthCheck(node);
if (nodeDepth > depth) {
depth = nodeDepth; //depth is a serialized property on this class
deepNode = node; //deepNode is a serialized property on this class
}
Undo.CollapseUndoOperations(group);
return node as T;
}
Thanks for your help!
EDIT: It seems what is happening is that because of the way Unity uses serialization for the Undo/Redo, the redo isn't able to connect the node created with the AddComponent, and the node that should be in the Parent's list. Like I said, this is likely due to how Unity is serializing them to handle Undo/Redo.
I did find a workaround to reconnect parent and child in the UndoRedo callback
void UndoRedoCallback() {
TreeNode[] allNodes = currentTree.GetComponents<TreeNode>();
ParentNode newParent = null;
//Looks for the parent missing a child
foreach (TreeNode node in allNodes) {
if (node is ParentNode) {
foreach (TreeNode child in ((ParentNode)node).Children) {
if (child == null) {
newParent = (ParentNode)node;
break;
}
}
}
}
if (newParent != null) {
//Looks for the child who is missing and adds them! Cancel Amber alert!
foreach (TreeNode node in allNodes) {
if (node.parent == newParent) {
if (!(node.parent.Children.Contains(node))) {
newParent.childrenActual()[newParent.Children.Count - 1] = node;
break;
}
}
}
}
}
Are we to assume that something happens to fields on parent
on that blank line between assigning group
and recording the parent?
@Adam-$$anonymous$$echtley I've updated the code snippet to more clearly show whats going on :)
Your answer
Follow this Question
Related Questions
How to Undo a lot of created objects at once? [Solved] 1 Answer
c# process that runs a batch file for blender exporting gets paused/stalled 0 Answers
Any way to set AnimatorOverrideController's animation clips programatically? 1 Answer
How to dynamically instanciante SpeedTree assets from script? 2 Answers