- Home /
Recording destroyed object inside OnDestroy() method
I have a custom editor made to create graphs. Usually the nodes can be deleted using the editor tools, so when I destroy the node object I can just call:
Undo.DestroyObjectImmediate(this);
The problem comes when the user doesn't use the editor, I want to fully implement this case since it's something that can happen and I don't want users to break the whole graph when deleting nodes directly, so I implemented the following method inside the "Node" class:
[ExecuteInEditMode]
private void OnDestroy() {
for (int i = 0; i < outs.Count; ++i) unlinkFrom(outs[i]);
for (int i = 0; i < ins.Count; ++i) ins[i].unlinkFrom(this);
Undo.RecordObject(getParent(), "destroyed");
getParent().remove(this);
}
This basically removes all the edges connecting to this node. But I wanted to implement an "Undo" function to this part too I tried the following things:
Record the object with the line
Undo.RecordObject(this)
at the beggining of the function, it still doesn't recover the references of adjacent nodesUsing the same line
Undo.DestroyObjectImmediate(this);
, it works! But an error pops out on the console saying that I can't call "DestroyImmediate" inside "OnDestroy".
Is there any way to record a destroyed object inside the "OnDestroy" function? Or a way to avoid that error message from showing up in the console?
Thanks!
Edit: Just for reference, this is the version that actually works but throws the error message on the console
[ExecuteInEditMode]
private void OnDestroy() {
for (int i = 0; i < outs.Count; ++i) {
Undo.RecordObject(outs[i], "destroyed");
unlinkFrom(outs[i]);
}
for (int i = 0; i < ins.Count; ++i) {
Undo.RecordObject(ins[i], "destroyed");
ins[i].unlinkFrom(this);
}
Undo.RecordObject(getParent(), "destroyed");
getParent().remove(this);
Undo.DestroyObjectImmediate(this);
}
Answer by Aridez · Nov 12, 2018 at 08:10 AM
After a ton of trial and error I managed to find a solution. The key to solving was to use the registerCompleteObjectUndo function. I'm currently using it on a free asset of mine in case you want to check out how all this works here. The relevant code is below in case it helps anyone with a similar problem:
private void OnDestroy() {
if (parent == null) return;
for (int i = 0; i < outs.Count; ++i)
Undo.RegisterCompleteObjectUndo(outs[i].waypoint, "destroyed");
for (int i = 0; i < ins.Count; ++i)
Undo.RegisterCompleteObjectUndo(ins[i], "destroyed");
Undo.RegisterCompleteObjectUndo(this.getParent(), "destroyed");
for (int i = outs.Count-1; i >= 0; --i) this.unlinkFrom(outs[i].waypoint);
for (int i = ins.Count-1; i >= 0; --i) ins[i].unlinkFrom(this);
Undo.RegisterCompleteObjectUndo(this, "destroyed");
this.getParent().waypoints.Remove(this);
}
Your answer
Follow this Question
Related Questions
OnDestroy in Editor - memory loss issue 1 Answer
Need help reassigning variables after the deletion of an object has been undone. 0 Answers
Can you use a more performant undo function than RegisterSceneUndo with DestroyImmediate? 2 Answers
EventType.ValidateCommand includes Undo? 0 Answers
Undo.RecordObject isn't working. 7 Answers