Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question Why do OnDisable and OnEnable get called when hitting undo?

Discussion in 'Scripting' started by dd_d_dd, Mar 22, 2024.

  1. dd_d_dd

    dd_d_dd

    Joined:
    Jul 8, 2014
    Posts:
    8
    Say I have a MonoBehaviour script with the `[ExecuteInEditMode]` attribute.
    Then if I make any change to the attached object (or any parent), e.g. moving the transform, and then hit ctrl-z to reset it, OnDisable and then OnEnable get called on my component, effectively resetting it. It's very problematic for me and I don't understand why it happens. I only want OnEnable and OnDisable to be called when the component is enabled or disabled... Or at least if I had a way of knowing whether it's a 'true' OnEnable or being called from a undo operation, that would be enough to workaround it.
    I can't find any documentation for this behaviour or any mention of it online.
    Any way to disable this or any workaround?
     
  2. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,470
    Just remove the ExecuteInEditMode
     
  3. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,410
    This is likely because of serialization which serializes the component, destroys it, and reserializes it.

    You can either make your state serializable like any public field, or you move that editor-only state to a SessionState instance which even survives domain reload.
     
  4. dd_d_dd

    dd_d_dd

    Joined:
    Jul 8, 2014
    Posts:
    8
    Thanks but I can't because the component is a tool meant to be used in edit mode

    Hm I guess it makes sense that state has to be de/serialized for an undo operation. But in my case losing state is not the problem. Basically my component spins up an intensive process which runs in a separate thread. I want that process to keep running as long as the component is enabled but kill it when the component is disabled. I don't care about undo/redo. But as far as i can tell there is no way for me to tell when the component is 'really' disabled or whether the user just hit ctrl-z! I can't think of any workaround for this that isn't very awkward. The best idea I have so far is to attach a callback to the undo event and ignore the OnDisable/OnEnable calls that happen right after. But that would be fragile and I wish it wasn't necessary
     
  5. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,410
    There's a tool for that. The EditorTool class. ;)

    Hooking into Undo events. But yes, it's awkward. But that's what happens when you try to make editor tools from runtime MonoBehaviours.
     
  6. dd_d_dd

    dd_d_dd

    Joined:
    Jul 8, 2014
    Posts:
    8
    Ah lol, fair point. I'll look into it, thanks
     
  7. dd_d_dd

    dd_d_dd

    Joined:
    Jul 8, 2014
    Posts:
    8
    Ryiah and Chubzdoomer like this.