Search Unity

Bug OnEnable() sees serialized values of enabled state on MonoBehaviour with [ExecuteAlways]

Discussion in 'Editor & General Support' started by marcospgp, Jan 25, 2022.

  1. marcospgp

    marcospgp

    Joined:
    Jun 11, 2018
    Posts:
    194
    I'm working on an editor script and ran into an issue where OnEnable() is being called "twice in a row" in the sense that serialized values are loaded from a previous enabled state.

    This is in accordance to the chart in this documentation page, but still seems like weird behavior.

    The order of events is ExitingEditMode -> OnBeforeSerialize (multiple times) -> OnDisable() -> OnBeforeSerialize -> OnAfterDeserialize -> OnEnable() -> OnDisable() -> OnAfterDeserialize -> OnEnable() -> EnteredPlayMode.

    In the last OnEnable(), I can see the serialized values of a previous enabled state. I would expect to see the serialized values of a disabled state.

    This breaks my component. It works by reading and modifying another component's value in OnEnable(), and restoring it to its original in OnDisable(). This means that in that last OnEnable(), I am modifying an already modified value.

    This means that for editor scripts, OnEnable() is effectively being called twice in a row as far as serialized values are concerned.

    Non serialized values, however, correspond to a disabled state, as expected.

    Shouldn't OnEnable() always see serialized values corresponding to a disabled state as well?

    Did I make it clear what the issue is here? Is there anything I can clarify further? Thank you!
     
  2. marcospgp

    marcospgp

    Joined:
    Jun 11, 2018
    Posts:
    194
    After handling the previous issue by keeping track of a
    isInitialized
    field that is serialized, I face a new issue:

    upload_2022-1-25_15-33-3.png

    I restore the mesh of a skinned mesh renderer component in OnDisable. Then, OnEnable sees the previous mesh on that component, not the one I restored.
    This happens in a very specific scenario: when renaming the folder that the prefab is stored in. This does not happen when disabling & reenabling the component.

    And more: If I unpack the prefab completely, I can no longer reproduce this issue. Something about the prefab being reloaded when its folder is renamed is undoing the mesh restoring that I do in OnDisable.

    It seems that I simply cannot rely on OnDisable/OnEnable for turning my component off and on, especially when relying on manipulating other components in the same object.
     
    Last edited: Jan 25, 2022