Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. We've updated our Terms of Service. Please read our blog post from Unity CTO and Co-Founder Joachim Ante here
    Dismiss Notice
  4. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    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.