Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. We're looking for your feedback on the platforms you use and how you use them. Let us know!
    Dismiss Notice
  4. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  6. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  7. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  8. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Recording destroyed object inside OnDestroy() method

Discussion in 'Extensions & OnGUI' started by Aridez, Apr 7, 2018.

  1. Aridez


    Feb 12, 2014
    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:


    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:

    Code (CSharp):
    1. [ExecuteInEditMode]
    2.         private void OnDestroy() {
    3.             for (int i = 0; i < outs.Count; ++i) unlinkFrom(outs[i]);
    4.             for (int i = 0; i < ins.Count; ++i) ins[i].unlinkFrom(this);
    5.             Undo.RecordObject(getParent(), "destroyed");
    6.             getParent().remove(this);
    7.         }
    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 beginning/end of the function, it still doesn't recover the references of adjacent nodes

    • Using the same line "Undo.DestroyObjectImmediate(this)" at the end of the function, 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?


    Just for reference, this is the version that actually works throwing the error message on the console

    Code (CSharp):
    1.     [ExecuteInEditMode]
    2.     private void OnDestroy() {
    3.         for (int i = 0; i < outs.Count; ++i) {
    4.             Undo.RecordObject(outs[i], "destroyed");
    5.             unlinkFrom(outs[i]);
    6.         }
    7.         for (int i = 0; i < ins.Count; ++i) {
    8.             Undo.RecordObject(ins[i], "destroyed");
    9.             ins[i].unlinkFrom(this);
    10.         }
    11.         Undo.RecordObject(getParent(), "destroyed");
    12.         getParent().remove(this);
    13.         Undo.DestroyObjectImmediate(this);
    15.     }
  2. NoBrainer-David


    Jan 5, 2014
    You have to start recording the object before you make changes to it, otherwise those changes can't be recovered. In your first code example, maybe just move the line where you start recording the object to the top?
    If ins[] and outs[] is not part of the current type, but of whatever getparent() returns, that might also be the problem why it is not recording that change.

    I would need to see more of your node class hierarchy to make any more suggestions.
  3. Aridez


    Feb 12, 2014
    Hey thanks for the reply!

    In the end I got it working using the "Undo.RegisterCompleteObjectUndo()" function. It seems that when dealing with object destruction using that makes a difference.