Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

(Case 1209226) Awake is no longer called for some MonoBehaviour types

Discussion in '2019.3 Beta' started by Hyp-X, Jan 4, 2020.

  1. Hyp-X


    Jun 24, 2015
    Starting from 2019.3 Awake is no longer called for some MonoBehaviour types.

    It happens when
    - Reload Scene is disabled
    - The class has ExecuteInEditMode
    - Its parent class has no ExecuteInEditMode
    - The Awake() method is in the parent class

    This sounds like a strange situation to have, but it does happen and it wasn't an issue until now.

    Reported Case 1209226
    fherbst likes this.
  2. LeonhardP


    Unity Technologies

    Jul 4, 2016
    Issue tracker link with answer from the devs:

    "This is an intentional change and by design.

    See "Important differences due to skipping Scene Reload" in this thread:

    "ExecuteInEditMode/ExecuteAlways scripts are not destroyed/awaken - no OnDestroy/Awake calls for those.
    Watch out for Awake/OnEnable methods which check EditorApplication.isPlaying property - Awake is not called and OnEnable is called only when EditorApplication.isPlaying is already true on Play Mode change."

    For any further discussion regarding this issue, we recommend that you discuss it in the thread:"
  3. Hyp-X


    Jun 24, 2015
    The reason I reported the issue with a class hierarchy is this:

    The base class can be a Unity package, a third party package or any other library.
    The base class functionality is broken by inheriting and adding ExecuteInEditMode.
    This is usually done in order to extend the script with some editor functionality.

    It is not usually feasible to fix the original script.

    That being said, I've given up on disabling Reload Scene ever being usable in Unity.
    When I wrote a code analyzer to find possible issues due to property serialization and stuff I got more hits in the Unity packages that we use than in our code.
  4. QFSW


    Mar 24, 2015
    I'm interested in this analyser. Is it Rosylyn or your own custom deal?
  5. Hyp-X


    Jun 24, 2015
    It's just using reflection to find fields that are serialized by unity.
    It also spawns the MonoBehaviour to check with reflection if the field is initialized in the constructor.

    For example:
    private List<int> foo;

    would give a warning (unless it is hand initialized in the constructor which is rare)
    private List<int> foo = new List<int>();

    wouldn't give a warning.

    The first one gives a warning because will be null by default, but will change into an empty list upon domain reload.
    And it's quite unexpected because people usually don't expect private fields to be a serialized.

    If it's a normal serialized field, than the code already had to deal with this issues in previous Unity versions, so no warning needed.
    The same is true for ScriptableObject's because they are not affected by scene reload.

    The analyzer is still incomplete though, as it doesn't descend deeper into structs and classes.
    For example if you have:
    private FooClass foo = new FooClass();

    It should check for null fields inside foo. They might be non-null initialized in the FooClass constructor.
    Same with a struct except structs are even harder to initialize in C# (they can't have a default constructor)
    alexeyzakharov likes this.
  6. alexeyzakharov


    Jul 2, 2014
    The motivation for the change was to avoid reinitialization of an object twice. But yes, the subsequences of the change makes disabled Reload Scene not really applicable to a lot of existing projects.
    We are reopening this case and looking into how we can address it.
    firstuser, TextusGames and Peter77 like this.