未调用 ScriptableObject 的 OnEnable 函数
OnEnable function from of ScriptableObject not being called
在下面的脚本中,如何获取脚本在 Assets 文件夹中的路径?
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 );
}
}
问题是 OnEnabled
它没有被调用,而且似乎获取脚本路径的唯一方法是通过 AssetDatabase.GetAssetPath
,这需要一个实例。
Unity 中的版本是 5.5.0b3。
要从ScriptableObject
继承时调用OnEnable()
函数,您必须从ScriptableObject
class.[=18调用CreateInstance()
函数=]
[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);
}
}
另一种使用 ScriptableObject.CreateInstance
的方法是从另一个脚本调用它。
[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);
}
}
测试:
public class Test : MonoBehaviour
{
public MyWindow myWindow;
public void OnEnable()
{
if (myWindow == null)
myWindow = Object.FindObjectOfType<MyWindow>();
if (myWindow == null)
myWindow = ScriptableObject.CreateInstance<MyWindow>();
}
}
根据我的经验,仅当活动场景组件引用 SO 的实例时,才会调用脚本对象 (SO) 上的所有“事件方法”(OnEnable、Awake 等)。仅仅创建一个实例是不够的。这与“SO 生活在场景之外”的说法相反。
在编辑器中特别混乱。一个可以例如在项目的资产中创建一个 SO 的实例,它看起来就像您期望的那样调用 OnEnable、Awake...。但是一旦你在编辑器之外构建和 运行 游戏,如果 SO 实例没有分配给活动场景对象或由脚本以另一种方式加载,这些方法将不会再被调用,但只存在于资产中。
此外,我无法确定编辑器何时决定加载或 re-load 仅存在于资产中的 SO 实例。根据我的经验,这是非常不一致和不可靠的。
我读到在 2018 年版本的 Unity 之前,有更多的错误导致这些方法与 SO 一起发出,现在它更可靠,但 documentation on SOs is still inaccurate 今天会产生误导。
在下面的脚本中,如何获取脚本在 Assets 文件夹中的路径?
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 );
}
}
问题是 OnEnabled
它没有被调用,而且似乎获取脚本路径的唯一方法是通过 AssetDatabase.GetAssetPath
,这需要一个实例。
Unity 中的版本是 5.5.0b3。
要从ScriptableObject
继承时调用OnEnable()
函数,您必须从ScriptableObject
class.[=18调用CreateInstance()
函数=]
[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);
}
}
另一种使用 ScriptableObject.CreateInstance
的方法是从另一个脚本调用它。
[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);
}
}
测试:
public class Test : MonoBehaviour
{
public MyWindow myWindow;
public void OnEnable()
{
if (myWindow == null)
myWindow = Object.FindObjectOfType<MyWindow>();
if (myWindow == null)
myWindow = ScriptableObject.CreateInstance<MyWindow>();
}
}
根据我的经验,仅当活动场景组件引用 SO 的实例时,才会调用脚本对象 (SO) 上的所有“事件方法”(OnEnable、Awake 等)。仅仅创建一个实例是不够的。这与“SO 生活在场景之外”的说法相反。
在编辑器中特别混乱。一个可以例如在项目的资产中创建一个 SO 的实例,它看起来就像您期望的那样调用 OnEnable、Awake...。但是一旦你在编辑器之外构建和 运行 游戏,如果 SO 实例没有分配给活动场景对象或由脚本以另一种方式加载,这些方法将不会再被调用,但只存在于资产中。
此外,我无法确定编辑器何时决定加载或 re-load 仅存在于资产中的 SO 实例。根据我的经验,这是非常不一致和不可靠的。
我读到在 2018 年版本的 Unity 之前,有更多的错误导致这些方法与 SO 一起发出,现在它更可靠,但 documentation on SOs is still inaccurate 今天会产生误导。