We all know ScriptableObject calls are somewhat random, Awake(), OnEnable() - you never really know when they are executed.
Reset() seems to be not executed at all.
And now, since Unity 2020.1.x, I think when the new QuickSearch-Features arrived, the OnEnabled() calls in ScriptableObjects are executed from another Thread.
Unity itself isn’t threadsafe, meaning that any calls in the OnEnable() to the UnityAPI or static fields that should be initialized can cause issues.
Is the result of this call:
(when duplicating an ScriptableObject Asset in the Project Window)
As you can see, I wrote a workaround, subscribing to EditorApplication.update, then executing the code, then checking if the class still exists or is NULL …
(Code below)
This workaround is quite a bit of boilerplate - can we instead have a OnEnable() Method in ScriptableObjects that is only called on the main thread?
And a default OnSceneLoaded() Method would also be quite cool for many different reasons.
(if anyone has a better, cleaner workaround, please tell me)
static List<DbEntrySO<TDBEntrySO>> _entriesToRegister = new List<DbEntrySO<TDBEntrySO>>();
protected override void OnEnable()
{
base.OnEnable();
#if UNITY_EDITOR
Debug.Log("Add ME " + name, this);
_entriesToRegister.Add(this);
UnityEditor.EditorApplication.update -= Register;
UnityEditor.EditorApplication.update += Register;
#else
RegisterEntry(this);
#endif
}
static void Register()
{
Debug.Log("_entriesToRegister.Count " + _entriesToRegister.Count);
foreach(DbEntrySO<TDBEntrySO> entry in _entriesToRegister)
{
if(!entry) continue; // is NULL when executed from [Worker0] Thread
RegisterEntry(entry);
}
_entriesToRegister.Clear();
UnityEditor.EditorApplication.update -= Register;
}
static void RegisterEntry(DbEntrySO<TDBEntrySO> entry)
{
string tempID = ScriptableDB<TDBEntrySO>.Register(entry as TDBEntrySO);
if (tempID != entry.ID)
{
entry._ID = tempID;
}
}