Notifications
Article
C#反射——掀起Unity Editor面纱
Published 5 months ago
1.1 K
3
论如何抓取Editor内部API
之前在群里看到有人提到 Profiler Memory Plus这个插件,相当不错~在原来Profiler功能上扩展出了diff功能 非常实用。
然后我就在想这个是怎么做的呢,某天在折腾shader keyword的时候突然灵光一闪,莫非是private API搞的? 动手试了下果然可行。
具体解释一下:Unity引擎底层是用C++写的,但是外围逻辑绝大部分都是C#实现,包括Editor本身。平常我们常见的UnityEngine.dll和UnityEditor.dll里就有大量的宝藏值得挖掘,官方已经提供了UnityCsReference参考。我个人觉得可以分为两类:
  • Undocument API 在代码里可以直接调用,但是并没有在文档里出现
  • Private API 无法在代码里直接调用,一般是internal class或者private作用域
但是谁让这些代码是人见人爱的C#代码呢!在编辑器下完全可以使用反射来绕开这个限制。具体来说举个例子,如果我们希望访问到ProfilerWindow里的某个私有变量m_ProfilerWindow
private static List<ProfilerWindow> m_ProfilerWindows = new List<ProfilerWindow>();
完全可以这么写
m_ProfilerWindows = tProfilerWindow.GetField("m_ProfilerWindows", BindingFlags.NonPublic | BindingFlags.Static); IList windows = m_ProfilerWindows.GetValue(null) as IList;
这样直接绕开了internal和private双重限制。在这个思路下,三下五除二就自己实现了想要的功能
最后也不得不提示这样做的缺点:
  • 反射在性能上还是有不少损失的
  • 如果Unity升级导致变量名变动等,就会代码出错需要人肉维护…
顺便如果想深入挖掘这块宝藏的话,dnSpy可以直接拿来调试:调试菜单-附加到进程(Unity)即可,断点、变量等功能均可使用。

不过总得来说,作为编辑器扩展非常靠谱,最近用这个思路还折腾了不少事情,譬如设置Material Inspector面板的Reflection Probe/完美抓取shader keyword等。这酸爽感觉就是打开了一个新世界的大门(逃
Tags:
钱康来
摸鱼程序员 - Programmer
3
Comments
钱康来
5 months ago
摸鱼程序员
柒月的鱼反射很好用,但是也让代码逻辑变模糊了
反射属于没办法的时候取巧的🤓
0
y
yesterday_time
5 months ago
柒月的鱼反射很好用,但是也让代码逻辑变模糊了
模块化后,还好
0
柒月的鱼
5 months ago
一个想成为独立游戏开发者的准备者
反射很好用,但是也让代码逻辑变模糊了
0