(Solved, but unhappy)ScriptableObject.Awake never execute

Hello!
On ScriptableObject.Awake documentation, It says:

But the problem is that this function is never called! I’m using 2017.1.
Is there something wrong?
None of these work:

void Awake() {
   Debug.Log("Test!");
}
private void Awake() {
   Debug.Log("Test!");
}
public void Awake() {
   Debug.Log("Test!");
}
protected void Awake() {
   Debug.Log("Test!");
}

So, someone manage to make it work??? I need this soooo badly to avoid making any “jerry-rig” code.

11 Likes

Oh well… I created a report: https://fogbugz.unity3d.com/default.asp?943003_3rnv3sufsjhjjeff

Since I’m not able to use Awake function on ScriptableObjects, I had to create an Init() function and now I have to call Init() everytime on the Awake gameobject, runing a foreach fr every ScriptableObject attached and I do the same for every other ScriptableObject that it is attached inside my others ScriptableObjects.

Really not a good way to do the coding on this scripts. Bad! Very bad!
I’m open to suggestions, solutions, whatever… This is giving me a nervous tic, everytime I have to call this Init function.

1 Like

So. I got an answer from Unity about the report.

I have to test it and IMHO, Devs: Take a kind look at this!

The first Test I made

The scripts are simple:

using UnityEngine;

namespace Game.Test {
   public class Test : MonoBehaviour {
      public TestSO testing;
   }
}
using UnityEngine;

namespace Game.Test {
   public class TestSO : ScriptableObject {
      protected virtual void Awake() { }
   }
}
using UnityEngine;

namespace Game.Test {
   [CreateAssetMenu (menuName = "Test/Testing ScriptableObject")]
   public class TestChildSO : TestSO {
      protected override void Awake () {
         base.Awake ();
         Debug.Log("Testing");
      }
   }
}

Observation: I created the ScriptableObject file on an folder and attached to the slot on the gameObject in inspector.
I thought it required the Awake function on the base class, but when I run, it doesn’t work! So…

The Second Test I made

Since the first test didn’t work I add some code to the Test class:

private void Awake() {
   testing = (TestSO) ScriptableObject.CreateInstance(typeof(TestChildSO));
}

And it work!

Conclusion: In my point of view, this method should be renamed to OnCreated. Why is that: Simple, the Awake does not run if a GameObject is on the scene, but only if a script creates the ScriptableObject!

When a Object is Awakening, ( if the ScriptableObject have the same method and the documentation says that it works similar way as MonoBehaviour, ) then the ScriptableObjects must execute Awake too! Otherwise it’s purpose lacks meaning! It is an OnCreated execution! More logic and coherence. Remember: this is my point of view and my argument!

43 Likes

Thank you for posting this. It explains a lot and I agree with you, it should be called OnCreate() Instead. Maybe is some inheritance shenanigans.

7 Likes

Totally agree.
Thanks for posting.

1 Like

Just discovered this. Wasted some time on it.

8 Likes

I just have this problem and found this post. Thanks for saving my time.

1 Like

try OnEnable Instead ?

OnEnable will be executed when Editor is not in playmode and an instance is assigned to a gameobject’s script’s parameter. So, this is not good.

The documentation is incorrect here, it’s an ambiguous and misleading statement.

But for consistency Awake() is plenty clear. Both Mobobehaviors and ScriptableObjects must have an instance alive and running in a scene in order to get their built-in calls. It’s already known how Awake() works - only fired once when the object is instanced - so why bother creating a new built in call that is executed exactly the same?

4 Likes

Hi all, scriptable call Awake when my game open on android device , but when Editor play, it’s not trigger ??? im so confuse -_-

I decided to load the scriptableObjects asset from Resources. But I don’t know if this single asset contains 1000 different references (gameobjects, sprites, etc), will it affect performance?

1 Like

I tested it. Look like the editor version is act different from the built version. In editor version, Awake will not be called by created scriptable. But in built version, it will be called. I assume that the built version will re-create all scriptable every time we start game so all Awake will be called.

The main issue here that i wrote about it, is because of the statement on documentation.
Please make sure you ready well my 3rd post , because it explain well. The Awake only run on scriptableobject when created, not loaded. To me this never make sense to be called Awake. On build version, the awake is called because the engine need to create the scriptableobjects to be ready.

It’s a OnCreated method. Not Awake method.
I don’t know how to explain better. I even give example script above to show whether this is true or not! On my Statecontroller i even created a Setup method which i call it everytime i load the script, because i need some settings to be set before update starts.

2 Likes

This is my workaround.

  1. Create a derived class from scriptable object with functions for the callbacks ( OnAwake() ), I called it monoscriptableObject.
  2. Create a scriptable object with a list that references the new monoscriptableObjects that need normal monobehaviours callbacks, I called it MonoCallBacks.
  3. Create a monobehaviour with a reference to the list in point 2 that calls those functions when their callbacks are called. ie. OnEnable() { foreach mso in list { mso .OnEnableCallBack() }}
  4. Have an instance in your scene of MonoCallBacks.

It’s a bit of a hassle, but works for me.

Not quite.
I’ve debugged this to death and back because I was wondering the same thing.

There are 3 different cases that will cause a ScriptableObject to call Awake()

1 - When it’s created. (Editor Only)
2 - When a scene which contains an object that references the asset is loaded.
3 - When the asset is first selected in the project window IF Awake() hasn’t already been called. (Editor Only)

Please correct me if I’m wrong, but in all the tests I’ve done, I’ve found this to be the consistent behaviour.

1 Like

I forgot that SOs can be created at runtime, so point 1 should happen in editor and out of editor.

Exactly what I found.
OnAwake is an unfortunate name. Unity Devs?

I’ve compiled a detailed description of when ScriptableObjects receive their callbacks and for what reasons here:

Since this thread pertains to the Awake() callback, the linked thread is relevant.

3 Likes