大家都知道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. [Java]刷题中的Java基础

    数组 取数组长度是属性length ArrayList ArrayList<Integer> maxRootHeap = new ArrayList<Integer>(); m ...

  2. JVM学习04:类的文件结构

    JVM学习04:类的文件结构 写在前面:本系列分享主要参考资料是  周志明老师的<深入理解Java虚拟机>第二版. 类的文件结构知识要点Xmind梳理

  3. LAB6 SOAP

    有web服务的,需要Deploy一下才能跑 通过ls看所有文件的所在地,cd进入对应文件夹,才可以编译 javac 编译,Java是执行 URL必须是WSDL文件点进去里面的:http://local ...

  4. systemd 编写服务管理脚本---学习

    转载:https://www.cnblogs.com/sparkdev/p/8521812.html 我们运行 linux 服务器的主要目的是通过运行程序提供服务,比如 mysql.web serve ...

  5. anaconda使用方法

    我是用的win10.想写爬虫,所以使用了  anaconda .总结一下使用的方法. 安装阶段跳过.: 再终端输入  jupyter notebook  然后就会在. 浏览器显示一个网页.其实这个也不 ...

  6. ELT(数据仓库技术) 学习

    ETL工具比较: https://blog.csdn.net/wjandy0211/article/details/78611801 ETL之kettle使用总结:(批量.含常量)csv入库: htt ...

  7. 找不到org.restlet.ext.jackson 解决办法

    检出 转成maven工程 ,不过最后发现有两个包maven没有找到: <dependency> <groupId>org.restlet.jse</groupId> ...

  8. robotframework 连接mysql数据库

    1.安装databaselibrary.pymysql 通过cmd命令执行:pip install robotframework-databaselibrary 通过cmd命令执行:pip insta ...

  9. 基于IDEA工具 lombok 的使用

    一.简介 Lombok 是一种 Java™ 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO).它通过注解实现这一目的. 二.lombok的添加和常用注解 ...

  10. 选择文件,显示其路径在ListBox控件里

    private void btnSelect_Click(object sender, EventArgs e)        {            lbxFiles.Items.Clear(); ...