当我们写编辑器自定义工具的时候,会发现一些 Unity 编辑器中已在的按钮、菜单项并没有开放访问权限,而我们的工具又需要调用这些按钮、菜单的功能。怎么办呢?下面我们就以调用 Inspector 的锁定功能为例,利用反射来实现。
文章的内容也是提供一种思路,当碰到类似情况时,自己也可以按下面流程尝试
关于 Inspector 的锁定功能点这里查看
先看下最终效果
首先我们需要下载 dll 反编译工具 dnspy,在 这篇文章 里有介绍。直接从 GitHub 上下载,解压使用免安装
准备好了之后,打开 dnSpy, 找到 UnityEditor.dll 拖进 dnSpy 窗口,为了方便查看代码,我们把反编的代码导出工程。
UnityEditor.dll 路径是 Unity 安装目录\Editor\2019.3.0f3(我用的是这个版本)\Editor\Data\Managed\下
导出后会自动生成.sln 文件
双击.sln 打开工程,因为我们要找的是小锁子位于 Inspector 视图当中,所以我们搜索一下 Inspector 来确定接口位于哪个类里面
图中 InspectorWindow.cs 便是目标类。搜索一下关键词 “Lock”, 发现有个叫 isLock 的属性,这个属性就是控制小锁子的属性。
- 我用的是 Unity 2019.3.0,早一些的版本中的类名和属性名可能不相同,需要自己判定。比如 Unity 2018 中的类名是 Inspector.cs
- 至于怎么找对应的接口或属性,终极大法: 连猜带蒙
找到了对应的属性,我们就开始写代码来实现调用了,由于 InspectorWindow.cs 有访问权限限制,所以我们用反射来调用并修改
代码很简单,贴出来
using UnityEditor;
using System;
public class TestLock : Editor
{
protected static bool isLock;
//添加菜单项
[MenuItem("Tools/Test Lock")]
static void Lock()
{
Type t = typeof(EditorWindow).Assembly.GetType("UnityEditor.InspectorWindow");
var window = EditorWindow.GetWindow(t);
isLock = !isLock;
t.GetProperty("isLocked").SetValue(window, isLock);
}
}
欢迎关注公众号,定期分享Unity的实用技巧~~