大家都知道Unity是一个C/C++的游戏引擎,C#只是Unity提供的脚本层。因此大部分功能都是通过C#来调用底层的C++代码的。而一些朋友可能不知道的是,其实Unity的C#代码中也有很多方法是我们不能直接调用的非公共方法,一个常见的情景是在拓展Editor时,除了Unity提供的公共方法之外,我们还可以通过反射的方式,调用一些Unity提供的内部方法来实现一些特殊的功能。

至于Unity的C#代码都有哪些内容,各位可以在这里找到答案:

https://github.com/MattRix/UnityDecompiled

当然C#部分的代码并没有什么实际的操作,但是它能告诉我们有哪些方法我们可以调用。

一个有趣的例子就是如何在Editor中完全关闭Gizmo呢?一个很简单但是我们正常情况下无法调用的方法就是来干这事的。

internal static extern void SetGizmoEnabled(int classID, string scriptClass, int gizmoEnabled);

所以,我们就可以通过C#的反射机制,在自己的脚本中调用Editor内封装的非公共方法来实现。

using System;
using System.Collections;
using System.Reflection;
using UnityEditor; public class SceneViewGizmos
{ #region 方法 [MenuItem("temp/Disable All Gizmos")]
private static void DisableAllSceneGizmos()
{
ToggleGizmos(false);
} [MenuItem("temp/Enable All Gizmos")]
private static void EnableAllSceneGizmos()
{
ToggleGizmos(true);
} private static void ToggleGizmos(bool gizmosOn)
{
int val = gizmosOn ? 1 : 0;
Assembly asm = Assembly.GetAssembly(typeof(Editor));
Type type = asm.GetType("UnityEditor.AnnotationUtility"); if (type == null)
{
return;
} MethodInfo getAnnotations = type.GetMethod("GetAnnotations", BindingFlags.Static | BindingFlags.NonPublic);
MethodInfo setGizmoEnabled = type.GetMethod("SetGizmoEnabled", BindingFlags.Static | BindingFlags.NonPublic);
MethodInfo setIconEnabled = type.GetMethod("SetIconEnabled", BindingFlags.Static | BindingFlags.NonPublic);
var annotations = getAnnotations.Invoke(null, null); foreach (object annotation in (IEnumerable)annotations)
{
Type annotationType = annotation.GetType();
FieldInfo classIdField = annotationType.GetField("classID", BindingFlags.Public | BindingFlags.Instance);
FieldInfo scriptClassField = annotationType.GetField("scriptClass", BindingFlags.Public | BindingFlags.Instance);
if (classIdField != null && scriptClassField != null)
{
int classId = (int)classIdField.GetValue(annotation);
string scriptClass = (string)scriptClassField.GetValue(annotation);
setGizmoEnabled.Invoke(null, new object[] { classId, scriptClass, val });
setIconEnabled.Invoke(null, new object[] { classId, scriptClass, val });
}
}
} #endregion
}

UnityTips:使用反射调用内部方法拓展编辑器的更多相关文章

  1. VS2010 F5调试时出现:“ 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常”解决

    VS2010 F5调试时出现 尝试运行项目时出错:未捕获通过反射调用的方法引发的异常 两个解决方法:1) 打开项目属性,选择调试选项卡,将“启用非托管代码调试”一项钩上.2) 打开项目属性,选择调试选 ...

  2. 反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性、字段),而不去使用Invoke方法)

    反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性.字段),而不去使用Invoke方法)   创建Delegate (1).Delegate.CreateDelegate(Type, ...

  3. JNI C反射调用java方法

    前面记录了调用C的学习笔记,现在来记录一下C反射调用Java的笔记.JNI开发学习之调用C方法 Android开发中调用一个类中没有公开的方法,可以进行反射调用,而JNI开发中C调用java的方法也是 ...

  4. java动态载入指定的类或者jar包反射调用其方法

    序言 有时候.项目中会用到java动态载入指定的类或者jar包反射调用其方法来达到模块的分离,使各个功能之间耦合性大大减少,更加的模块化.代码利用率更高.模式中的代理模式就用到java的这一机制. 下 ...

  5. 从vs2010的UnitTestFramework类库提取私有方法反射调用的方法

    背景 年龄大点的程序员都知道在vs2010中创建单元测试非常的简单,鼠标定位在方法名字,右键创建单元测试,就会创建一个测试方法,即使是在私有方法上也可以创建测试方法. VS2010以后就没这么简单了, ...

  6. 对JAVA Bean使用PropertyDescriptor反射调用JAVA方法低耦合

    对于符合JAVA Bean规范的bean,调用其方法应优先使用java.beans.PropertyDescriptor获取Method进行方法调用,以获得更大的可维护性. public void g ...

  7. 将对象转为数组方法:延伸array_map函数在PHP类中调用内部方法

    public static function objectToArray($d) { if (is_object($d)) { $d = get_object_vars($d); } if (is_a ...

  8. 对JAVA Bean使用PropertyDescriptor反射调用JAVA方法

    对于符合JAVA Bean规范的bean,调用其方法应优先使用java.beans.PropertyDescriptor获取Method进行方法调用,以获得更大的可维护性. 示比例如以下: NonCo ...

  9. java反射调用私有方法和修改私有属性

    //调用私有方法package com.java.test; public class PrivateMethod { private String sayHello(String name) { r ...

随机推荐

  1. bootstrap模态框手动关闭遮盖层不消失

    模态框中 加载了一个子页面 子页面中调教表单之后想根据执行结果手动关闭模态框,最初尝试了以下几种方案: 1.$("#myModal").modal('hide');//模态框关闭 ...

  2. paloalto防火墙执行初始配置

    1.默认情况下,防火墙的 IP 地址为 192.168.1.1,用户名/密码为 admin/admin. 为了安全起见,在继续执行其他防火墙配置任务之前,必须更改这些设置.必须从 MGT 接口(即使计 ...

  3. java基础 ---- 一维数组

    为什么要使用数组: 因为不使用数组计算多个变量的时候太繁琐,不利于数据的处理. --------   数组也是一个变量,是存储一组相同类型的变量 声明一个变量就是在内存中划出一块合适的空间 声明一个数 ...

  4. VBA 删除Excel中所有的图片

    Sub DeletePic()     Dim p As Shape     For Each p In Sheet1.Shapes         If p.Type = Then         ...

  5. Java-HashMap、HashSet、hashTable

    HashMap:key:可null,重复的key对应的value会出现后面覆盖前面的情况.value:可null; 引用:数组,数组中存链表. HashSet使用HashMap的实现存储数据,所以有H ...

  6. spring boot利用controller来测试写的类

    我们在开发spring boot应用程序的时候,往往需要测试某个写好的类,但是在测试的时候发现不太好测试,用Junit等测试框架,总是会报一些问题,大致是找不到配置文件以及无法利用spring创建的对 ...

  7. Vue 中使用 viewerjs进行本地上传预览图片

    https://www.cnblogs.com/shenjp/p/9754171.html 如果图片路径是 接口的返回信息的话,将路径存储在数组中,在this.$nextTick中实例化Viewer: ...

  8. WIN10 安装 ReportBuilder3.msi 提示需要 .NET Framework 4.5

    win+r键调出运行窗口输入regedit打开注册表,找到HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/NET Framework Setup/NDP/v4/Client ...

  9. 如何在SpringBoot项目中使用拦截器

    相比springmvc,springboot中拦截器不需要在xml中配置,只需定义拦截器类 implements HandlerInterceptor 和拦截器拦截路径的配置类extends WebM ...

  10. 正确JAVA从本机获取IP地址的方法

    https://www.cnblogs.com/xiaoBlog2016/p/7076230.html