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放置位置截图: