Search Unity

ScriptableObject gets destroyed in Editor when created in OnEnable from another

Discussion in 'Editor & General Support' started by RRickkert, Jul 11, 2019.

  1. RRickkert

    RRickkert

    Joined:
    Jun 5, 2018
    Posts:
    6
    I'm messing around with some editor-time events which resulted in me encountering an issue which I cannot seem to find a workaround for.

    The scenario:

    I have a container class, extended from ScriptableObject.
    This container has a variable (child), which is of a class type that's also extended from ScriptableObject.
    In OnEnable(), an instance from this child is created using CreateInstance().
    This means that in the editor, when the container is created in the asset folder, this instance has a variable child which contains a reference to that created child.

    The issue:

    When entering play mode, the OnEnable() method is called again. All good so far. Everything works.
    Now, when exiting play mode. The child which was created in OnEnable is destroyed. Which would be okay, however, OnEnable on the container is not called again. Meaning, the instance isn't created anymore, resulting in some nullreference exceptions.

    Example code to reproduce this issue:

    Container:
    Code (CSharp):
    1. [CreateAssetMenu]
    2. public class Container : ScriptableObject
    3. {
    4.     [SerializeField]
    5.     private Child _child;
    6.  
    7.     private void OnEnable()
    8.     {
    9.         Debug.Log("[OnEnable]: Container");
    10.         _child = CreateInstance<Child>();
    11.     }
    12. }
    ScriptableObjectVariableClass:
    Code (CSharp):
    1. public class Child : ScriptableObject
    2. {
    3.     private void OnEnable()
    4.     {
    5.         Debug.Log("[OnEnable]: Child");
    6.     }
    7.     private void OnDestroy()
    8.     {
    9.         Debug.Log("[OnDestroy]: Child");
    10.     }
    11. }
    12.  
    Steps to reproduce this issue using the code above:

    Create an instance from Container in the asset folder using Right click --> Create --> Container.
    Notice the variable "Child" is set to "Type mismatch" (this is because it's created in code and cannot show you a direct reference to the asset in the asset folder, so correct).
    Notice the "[OnEnable]: Container" and "[OnEnable] Child" messages in your console.
    Press play.
    Notice the variable "Child" is still set to "Type mismatch".
    Notice the "[OnEnable]: Child", "[OnEnable] Container", "[OnEnable]: Child" and "[OnDestroy] Child" messages in your console.
    Press play again to exit play mode.
    Notice the variable "Child" is set to "Missing (Child)".
    Notice the "[OnDestroy]: Child" message in your console.

    My questions:
    - Why isn't OnEnable called again when exiting play mode?
    - Is there a way to prevent my child instance from being destroyed when exiting play mode?
    - Are there any workarounds for this issue?

    Hope someone can help me out here.

    Unity version: 2019.1.3f1
     
  2. Because the application is winding down. OnEnable only called when the game object/asset gets enabled. Exiting play mode is similar to application quit (not the same).
    Not really, unless you make it asset instead of an in-memory instance. Like your other scriptable object.
    There is, but in the other way around: https://forum.unity.com/threads/sol...ject-awake-never-execute.488468/#post-4483018
     
    RRickkert likes this.
  3. RRickkert

    RRickkert

    Joined:
    Jun 5, 2018
    Posts:
    6
    Thank you for your response!
    That makes sense! Thanks for clarifying!
    Sadly an asset in this case wouldn't be an option. That's a bummer though. I do see now why it would do that.
    Thank you for that link! I was able to solve my issue using that, I did have to modify the `ExitingPlayMode` into `EnteredEditMode` and call `OnBegin` instead of `OnEnd`, but that allowed me to effectively get a 'notify' when the play mode was completely destroyed and cleaned up, and the edit mode was loaded as well.
     
    Lurking-Ninja likes this.