拓展编辑器 2 - ProjectWindow

关键概念:

  • [InitializeOnLoadMethod] : 该修饰告诉 Unity ,被修饰的方法在脚本编译完后首先调用。必须时静态方法。

  • MenuItem(“Asset/XXX”) : 右键菜单。

  • [MenuItem(“Asset/Create/XXX”)] : 右键菜单,以及在窗口左上角的 Create菜单显示。

  • EditorApplication.projectWindowItemOnGUI : Project 绘制委托。签名:void OnGUI(string guid, Rect selectionRect)。

    • string guid: 资源的 guid
    • Rect selectionRect : 选中资源项的显示区域。
  • EditorApplication.projectChanged : 监听 Project 改变的委托。

  • string AssetDatabase.GetAssetPath(Object) : 获取资源的路径。

  • string AssetDatabase.AssetPathToGUID(string) : 将资源路径转换成 GUID。

  • bool GUI.Button(Rect rect, string name) : 在指定区域绘制按钮,返回用户是否点击。

  • GUI.colro : 指定 UI 绘制的颜色。

例子:

using UnityEditor;
using UnityEngine;

/// <summary>
/// 扩展 Project 窗口
/// 通过派生 UnityEditor.AssetModificationProcessor 监听资源状态时间
/// </summary>
public class ProjectWindowExtend : UnityEditor.AssetModificationProcessor
{
    // 右键菜单
    [MenuItem("Assets/My Tools/Tools", false, 1)]
    static void OnMyTool()
    {
        Debug.Log("Run my tool.");
    }

    // 右键菜单以及左上角的Create菜单
    [MenuItem("Assets/Create/My Create/Sphere", false, 1)]
    static void OnMyCreateSphere()
    {
        GameObject.CreatePrimitive(PrimitiveType.Sphere);
    }

    [InitializeOnLoadMethod]	// 脚本编译完成后首先调用
    static void InitializeOnLoadMethod()
    {
        // 绘制方法
        EditorApplication.projectWindowItemOnGUI += delegate (string guid, Rect selectionRect)
        {
            if (guid.Length > 0 && Selection.activeObject)
            {
                string path = AssetDatabase.GetAssetPath(Selection.activeObject);
                string assetGUID = AssetDatabase.AssetPathToGUID(path);
                if (guid == assetGUID)
                {
                    float width = 50.0f;
                    selectionRect.x += selectionRect.width - width;
                    selectionRect.y += 2;
                    selectionRect.width = width;
                    GUI.color = Color.red;
                    //点击事件
                    if (GUI.Button(selectionRect, "click"))
                    {
                        Debug.Log($"click: {Selection.activeObject.name}");
                    }
                    GUI.color = Color.white;
                }
            }
        };

        // 监听任意所有的变化
        EditorApplication.projectChanged += delegate ()
        {
            Debug.Log("changed");
        };
    }

    // 监听双击左键,打开资源事件,会调用很多次?
    public static bool IsOpenForEdit(string assetPath, out string message)
    {
        message = null;
        Debug.Log($"Open for eidt asset:{assetPath}");

        // 返回true表示允许打开资源,false表示不可以再unity中打开该资源
        return true;
    }

    // 监听资源将要被创建事件
    public static void OnWillCreateAsset(string path)
    {
        Debug.Log($"Will create asset:{path}");
    }

    // 监听资源将要被保存
    public static string[] OnWillSaveAsset(string[] paths)
    {
        for (int i = 0; i < paths.Length; ++i)
        {
            Debug.Log($"Will save assets:{paths[i]}");
        }
        return paths;
    }

    // 监听资源将要被移动事件
    public static AssetMoveResult OnWillMoveAsset(string oldPath, string newPath)
    {
        Debug.Log($"Will move asset form:{oldPath} to:{newPath}");
        // 告诉内部实现,该脚本已经进行了移动,内部实现将不再移动资源
        return AssetMoveResult.DidMove;
    }

    // 监听资源将要被删除事件
    public static AssetDeleteResult OnWillDeleteAsset(string assetPath, RemoveAssetOptions option)
    {
        Debug.Log($"Will delete asset:{assetPath}. option:{option}");
        // 告诉内部实现,该脚本没有删除资源,需要内部删除
        return AssetDeleteResult.DidNotDelete;
    }
}
发布了49 篇原创文章 · 获赞 2 · 访问量 2614
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章