unity编辑器扩展dll形式展示

发布于:2025-05-31 ⋅ 阅读:(24) ⋅ 点赞:(0)

1.背景:最近搞工程迁移发现一旦c#报错就会导致编辑器菜单没法使用,做了一些尝试发现使用dll的方式会是不错的选择。当然有些工具还是建议用外部的c#工程来写比如winform.

2.遇到的问题:我记得之前2017年左右的时候做一个unity的dll工程并不需要引入多少unity的内置dll一般引入UnityEngine.UI.dll 以及UnityEngine.dll就可以了

看看现在的编辑器使用的dll(你的目录\Unity\Hub\Editor\2021.3.41f1\Editor\Data\Managed\UnityEngine\一堆dll)

注:后续在制作工具的过程中发现UnityEngine.UI.dll拿不到 这样无法识别Image组件

遇到这种情况可以到你们项目的library目录,然后搜索UnityEngine.UI.dll 然后拷贝到你们的类库工程比如我这个UnityEditorExpand 然后右键项目添加dll引用

实例:SceneViewUI.cs 这个例子会比较直观 生成dll 放在unity的Assets/Plugin/Editor(自行构建)/xx.dll  以及xx.pdb(支持调试功能)

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

[InitializeOnLoad]
public class SceneViewUI
{
    static SceneViewUI()
    {
        // 订阅 SceneView.duringSceneGui 事件
        SceneView.duringSceneGui += OnSceneGUI;
    }

    private static void OnSceneGUI(SceneView sceneView)
    {
        //if(sceneView.camera.orthographic) // 如果是2d模式直接return 
        //{
        //    return;
        //}
        // 在 Scene 视图中绘制文本
        Handles.BeginGUI();
        var oldColor = GUI.color;
        GUI.color = Color.black;

        Rect sceneViewRect = SceneView.currentDrawingSceneView.position;

        // 计算 Box 在右下角的位置
        float boxX = sceneViewRect.width - 300;
        float boxY = sceneViewRect.height - 50;

        // 创建一个 GUILayout 区域,将其放置在右下角
        GUILayout.BeginArea(new Rect(boxX, boxY, 300, 100));
        // 创建一个 GUILayout.Box
        GUILayout.Box("按下F12直接跳转到选中gameObject对应的代码行");
        GUILayout.EndArea();

        Vector3 bottomLeftWorld = sceneView.camera.ViewportToWorldPoint(new Vector3(0, 0, sceneView.camera.nearClipPlane));
        Vector2 bottomLeftScreen = HandleUtility.WorldToGUIPoint(bottomLeftWorld);


        var rect = new Rect(bottomLeftScreen.x, bottomLeftScreen.y - 20, 200, 20);

        var size = GameViewTools.GameViewSize();
        string isLand = (size.x > size.y) ? "横屏" : "竖屏";
        GUI.Label(rect, $"屏幕({isLand})分辨率为:({size.x},{size.y})");
        GUI.color = oldColor;
        rect = new Rect(rect.x, rect.y - 20, 200, 20);
        if (GUI.Button(rect, "启动游戏"))
        {
            EasyUseEditorTool.OnSceneOpenOrPlay("Assets/scenes/GameStart.unity");
        }
        rect = new Rect(rect.x, rect.y - 20, 200, 20);
        if ((!EditorPrefs.GetBool("InitializerUiEdit", false) && GUI.Button(rect, "锁定分辨率"))
            || (EditorPrefs.GetBool("InitializerUiEdit", false) && GUI.Button(rect, "解除锁定分辨率")))
        {
            EditorPrefs.SetBool("InitializerUiEdit", !EditorPrefs.GetBool("InitializerUiEdit", false));
        }
        rect = new Rect(rect.x, rect.y - 20, 200, 20);
        if ((!EditorPrefs.GetBool("SelectionTools", true) && GUI.Button(rect, "资源自动展开"))
            || (EditorPrefs.GetBool("SelectionTools", true) && GUI.Button(rect, "解除资源自动展开")))
        {
            EditorPrefs.SetBool("SelectionTools", !EditorPrefs.GetBool("SelectionTools", false));
            AssetDatabase.Refresh();
        }
        rect = new Rect(rect.x, rect.y - 20, 200, 20);
        if ((!EditorPrefs.GetBool("customlog", false) && GUI.Button(rect, "开启自定义日志"))
            || (EditorPrefs.GetBool("customlog", false) && GUI.Button(rect, "关闭自定义日志")))
        {
            EditorPrefs.SetBool("customlog", !EditorPrefs.GetBool("customlog", false));
        }

        rect = new Rect(rect.x, rect.y - 20, 200, 20);
        if (GUI.Button(rect, "打包"))
        {
            var classType = Type.GetType("PackHelper,Assembly-CSharp-Editor");
            var binds = BindingFlags.Static | BindingFlags.Instance |
                        BindingFlags.Public | BindingFlags.NonPublic;

            var methodInfo = classType.GetMethod("BundleSetting",binds);

            methodInfo.Invoke(null,null);
            
        }

        rect = new Rect(rect.x, rect.y - 20, 200, 20);
        if (GUI.Button(rect, "资源冗余检查&清理资源"))
        {
            Resolution rs = Screen.currentResolution; //获取当前的分辨率 
            int nWidth = 600;
            int nHeight = 500;
            int x = (rs.width - nWidth) / 2;
            int y = (rs.height - nHeight) / 2;
            Rect rect2 = new Rect(x, y, nWidth, nHeight);
            FindRepeatRes myWindow = (FindRepeatRes)EditorWindow.GetWindowWithRect(typeof(FindRepeatRes), rect2, true,

     "资源查重&合并");
            myWindow.position = rect2;
            myWindow.Show();//展示 
            myWindow.closeAction += EditorLogWindow.CloseWindow;
            EditorCoroutine.StartCoroutine(new EditorWaitForSeconds(0.01f, () =>
            {
                EditorLogWindow.OpenWindow(myWindow);
                myWindow.Focus();
            }));


        }
   
        

        rect = new Rect(rect.x, rect.y - 20, 200, 20);
        if (GUI.Button(rect, "代码同步"))
        {
            CodeMoveTool.ShowWindow();
        }

        rect = new Rect(rect.x, rect.y - 20, 200, 20);
        if (GUI.Button(rect, "清理缓存"))
        {
            EditorPrefs.DeleteAll();
            PlayerPrefs.DeleteAll();
            string path = Application.persistentDataPath + "/GamebalootRankMatchResult.txt";
            if (File.Exists(path))
            {
                Debug.Log("清理GamebalootRankMatchResult成功");
                File.Delete(path);
            }
        }

        Handles.EndGUI();
    }
}

编辑器拓展界面截图:

dll生成 :

右键工程属性 点击生成->事件->生成后事件 配置如下:

xcopy "$(TargetDir)$(TargetName).dll" "D:\code_move1\Assets\Plugins\Editor\" /Y
xcopy "$(TargetDir)$(TargetName).pdb" "D:\code_move1\Assets\Plugins\Editor\" /Y

dll放置位置截图: