当 Unity 编辑器尝试打开资源时,会调用一个静态回调方法。
Unity 在尝试打开资源时会调用任何用 [OnOpenAssetAttribute]
修饰的静态方法,例如在编辑器中双击资源时。这提供了一个机会来实现自定义资源打开逻辑,或验证资源可以在 Unity 编辑器中打开,而不是在外部程序中打开。
该属性针对方法,并接受两个可选的位置参数
callbackOrder
: 第一个参数表示回调调用顺序的索引,必须为 int
类型。如果您有多个 OnOpenAssetAttribute 回调,并且希望按特定顺序调用它们,这将很有用。方法按升序数字顺序调用,从 0 开始。attributeMode
: 第二个参数是来自 OnOpenAssetAttributeMode 的 enum
值,指示修饰方法是在 Execute
模式下还是在 Validate
模式下调用。 Execute
模式用于实现某些自定义资源打开行为的回调。 Validate
模式用于检查编辑器是否可以打开资源。如果未指定,则默认模式为 OnOpenAssetAttributeMode.Execute.用 [OnOpenAssetAttribute]
修饰并在 Execute
模式下的方法必须具有以下签名之一
static bool OnOpenAsset(int instanceID)
static bool OnOpenAsset(int instanceID, int line)
static bool OnOpenAsset(int instanceID, int line, int column)
注意: 回调方法不必命名为 OnOpenAsset
,但其签名必须与显示的签名之一匹配。
用 [OnOpenAssetAttribute]
修饰并在 Validate
模式下的方法必须具有以下签名static bool OnOpenAsset(int instanceID)
在 OnOpenAssetAttributeMode.Validate 模式下,该方法不会打开资源,而是检查编辑器是否可以打开它。如果编辑器可以打开资源,则返回 true
,否则返回 false
。这等效于 AssetDatabase.CanOpenAssetInEditor 执行的检查。
版本控制系统集成主要使用此验证函数来确定要签出的文件。游戏对象、场景或用户制作的资源等本机资源返回 true
,因为它们在编辑器中打开和编辑。声音剪辑和纹理等资源返回 false
,因为它们在外部程序中打开和编辑。
另请参阅: OnOpenAssetAttributeMode、AssetDatabase.CanOpenAssetInEditor
// Return true if you handled the opening of the asset or false if an external tool should open it.
using UnityEngine; using UnityEditor; using UnityEditor.Callbacks;
public class MyAssetHandler : ScriptableObject { [OnOpenAssetAttribute(1)] public static bool step1(int instanceID, int line) { string name = EditorUtility.InstanceIDToObject(instanceID).name; Debug.Log("Open Asset step: 1 (" + name + ")"); return false; // we did not handle the open }
// step2 has an attribute with index 2, so will be called after step1 [OnOpenAssetAttribute(2)] public static bool step2(int instanceID, int line) { Debug.Log("Open Asset step: 2 (" + instanceID + ")"); return false; // we did not handle the open }
[OnOpenAsset(OnOpenAssetAttributeMode.Validate)] public static bool WillOpenInUnity(int instanceID) { if (AssetDatabase.GetMainAssetTypeAtPath(AssetDatabase.GetAssetPath(instanceID)) == typeof(MyAssetHandler)) { // We can open MyAssetHandler asset using MyAssetHandler opening method return true; } else return false; // The passed instance doesn't belong to MyAssetHandler type asset so we won't be able to open it using opening method inside MyAssetHandler } }