rraallvv rraallvv - 1 month ago 8
C# Question

OnEnable function from of ScriptableObject not being called

In the following script how can I get the path to the script in the Assets folder?

using UnityEngine;
using System.Reflection;
using System.IO;
using UnityEditor;

[InitializeOnLoad]
public class MyWindow : ScriptableObject
{
static string pathToScript;

[MenuItem("Window/My Window")]
static void Open()
{
// Do something with `pathToScript`
}

// This function is NOT called when the object is loaded.
protected void OnEnable()
{
var script = MonoScript.FromScriptableObject( this );
pathToScript = AssetDatabase.GetAssetPath( script );
}
}


The problem is that
OnEnabled
it's not called, also it seems the only way to get a path to the script is through
AssetDatabase.GetAssetPath
which requires an instance.

The version in Unity is 5.5.0b3.

Answer

For the OnEnable() function to be called while inheriting from ScriptableObject, you must call the CreateInstance() function from ScriptableObject class.

[InitializeOnLoad]
public class MyWindow : ScriptableObject
{
    static string pathToScript;
    static MyWindow windowInstance;

    [MenuItem("Window/My Window")]
    static void Open()
    {
        Debug.Log("Open:" + pathToScript);

        //Do something with `pathToScript`

        if (windowInstance == null)
            windowInstance = ScriptableObject.CreateInstance<MyWindow>();

    }

    protected void OnEnable()
    {
        Debug.Log("Enabled!");
        var script = MonoScript.FromScriptableObject(this);
        pathToScript = AssetDatabase.GetAssetPath(script);
    }
}

Another way to use ScriptableObject.CreateInstance is to call it from another script.

[InitializeOnLoad]
public class MyWindow : ScriptableObject
{
    static string pathToScript;

    [MenuItem("Window/My Window")]
    static void Open()
    {
        Debug.Log("Open:" + pathToScript);

        //Do something with `pathToScript`
    }

    protected void OnEnable()
    {
        Debug.Log("Enabled!");
        var script = MonoScript.FromScriptableObject(this);
        pathToScript = AssetDatabase.GetAssetPath(script);
    }
}

Test:

public class Test : MonoBehaviour
{
    public MyWindow myWindow;
    public void OnEnable()
    {
        if (myWindow == null)
            myWindow = Object.FindObjectOfType<MyWindow>();

        if (myWindow == null)
            myWindow = ScriptableObject.CreateInstance<MyWindow>();
    }
}
Comments