Unity[C#] Reflection Use

简介:



 

Reflection

Reflection是C#程序员的一个最有力工具

最常用的例子来说明反射的用处是一个插件系统。假设你正在创建一个 接受用户创建 的扩展程序,有没有办法预先知道哪些方法这个扩展他们有或有扩展的名字将是什么,除非你可以检查编译的程序集,并在运行时提取信息,这正是反射呢,等等

功能需求

目前,我正在使用Unity开发一个游戏,用户界面是在游戏中(3D UI)。这意味着我会使用Unity提供的API,它提供了相当强大的工具集来创建交互式图形用户界面的。

场景中的3D对象可以响应用户的输入。Unity让你检测鼠标事件,但没有办法用模块化的方法编写单个事件处理程序?

为了得到这个功能,我不得不扩展Unity的Editor和Inspecot 来暴露我的代码,这听起来很复杂,但这些定位方法,并随后调用它们的底层代码很简单。

interface2

实现思路及方法

1. 暴露你需要的方法

之前,我们接触过C#的Reflection API,我们需要创建一个新的属性

Attributes allow us to assign metadata to classes, methods, properties, etc. that can be read back by reflection.

属性允许我们指定方法,类属性等等,可以通过反射来读到这些值。

In this case, our attribute is going to be called “ExposeToEditor” and we're going to use it to tag instance methods (and classes with static methods) that Unity's editor should recognise as valid event handlers.

在这种情况下,我们的属性将被称为:ExposeEditor ,我们打算用它来标记Instance(和类的静态方法)Unity的Editor可以识别出它们是有效的事件处理程序

因此,我们创建了一个新的脚本文件,并确保 using Systm;,然后我们编写以下代码:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class ExposeToEditor : Attribute { }

这将创建一个标准属性系统,我们现在可以分配给任何方法或类,例如:

[ExposeToEditor]
 public void OnThisButtonClick(object sender) { };

现在,我们可以放在一起,将跟踪标识以这种方式方法的代码

2. 定位我们的Public的方法

inunity

点击上面的图像,将其展开,并期待在最右边的面板中-你会看到一个名为:Interface Click Handler的脚本。这是一个Editor的界面,我们编码,可以让我选择包含我所需要的脚本和方法的特定对象。此图片是更提供上下文是什么,我来解释,而不是使用Reflection的重要组成部分。因此,如果它没有多大,不用担心。

最重要的是这些背后的编辑器界面,它需要定位的方法在脚本的逻辑,下面是关键的部分

var type = t.OnClickMonoBehaviour.GetType(); List< string> methodNames = new List< string>(); List<MethodInfo> methods = new List<MethodInfo>(type.GetMethods()); foreach (MethodInfo mi in methods) { if (mi.IsDefined( typeof(ExposeToEditor), true)) { methods.Add(mi); methodNames.Add(mi.Name); } }

让我们把它分解,我们要做的第一件事情就是,获取选定的脚本类型,后者被存储 在 OnClickMonoBehaviour 对象的属性t。然后我们实例化一些List来存储这些方法的信息,foreach 循环遍历获取所有的包含在这个Script Type的public方法,通过type.GetMethods;

.GetMethods为我们提供一个数组的MethodInfo对象,.MethodInfo包含了大量的关于每个方法的信息,我们可以使用甚至该方法MethofInfo.Invoke.然而,这并不是最有效的方式来动态调用一个方法,以后的东西我会介绍。

现在,我们不希望来存储所有的方法,我们只是想通过那些我们先前创建的属性暴露出来,因此,我们使用MethofInfo.IsDefind() 方法来检查是否 ExposeToEditor 连接到该方法。要彻底,我们告诉 IsDefind 检查继承的类型也是如此。

一旦循环完成之后,我们将不得不包含的方法作为字符串不只是名字,但是这些方法本身,在形式列表 MethofInfo 对象。的字符串列表是用来填充的最后一个影像的”关于Click 方法” 下拉列表中,这样我们就可以很容易地选择正是我们所需要的。

3. 存储和动态调用方法

用方法名存储,所有我们现在需要做的是理清了“Click” 的逻辑,这是用来在游戏中,正如我们前面提到的,要做到这一点最简单的方式是通过使用MethodInfo的动态调用。例如:

MethodInfo mi = VariableContainingMethodInfo;
mi.Invoke();

并没有什么真的错了,这干得不错,但是,我们可以执行通过使用  Action<T> Delegate 并缓存它

首先,我们在某处定义缓存变量

private Action<object> CacheAction;

然后,当界面元件由玩家互动,我们缓存的方法,并用它在随后的相互作用。

CachedAction = (Action<object>)Delegate.CreateDelegate(typeof(Action<object>),OnClickMonoBehaviour,OnClickMethod);

现在,有几个重载 Delegate.CretaeDelegate ,在这种情况下 OnClickMonoBehaviour 和 OnClickMethod 都是字符串。委托创建并存储在CacheAction ,所以当我们要调用它,我们只是这样做:

CacheAction(object);

在这儿 object 只是一个灵活的参数,我们可以根据需要将信息传递到事件处理程序。

The best way to get more familiar with it is to check it out on MSDN. For more practical examples, Stack Exchange is a valuable resource, providing specific examples of how to get reflection doing what you want it to.

本文转自赵青青博客园博客,原文链接:http://www.cnblogs.com/zhaoqingqing/p/3848350.html,如需转载请自行联系原作者


相关文章
|
6月前
|
存储 C# 图形学
【Unity 3D】C#数据类型和变量、命名规范的讲解(附源码)
【Unity 3D】C#数据类型和变量、命名规范的讲解(附源码)
156 1
|
6月前
|
存储 人工智能 C#
【Unity 3D】C#中数组、集合、栈、队列、哈希表、字典的讲解(附测试代码)
【Unity 3D】C#中数组、集合、栈、队列、哈希表、字典的讲解(附测试代码)
82 0
|
6月前
|
搜索推荐 算法 C#
【Unity 3D】C#中冒泡排序、选择排序、插入排序等算法的详解(附源码 超详细)
【Unity 3D】C#中冒泡排序、选择排序、插入排序等算法的详解(附源码 超详细)
116 1
|
6月前
|
程序员 C# 图形学
【Unity 3D】C#中条件语句if else switch的讲解
【Unity 3D】C#中条件语句if else switch的讲解
148 1
|
3月前
|
图形学 C# 开发者
全面掌握Unity游戏开发核心技术:C#脚本编程从入门到精通——详解生命周期方法、事件处理与面向对象设计,助你打造高效稳定的互动娱乐体验
【8月更文挑战第31天】Unity 是一款强大的游戏开发平台,支持多种编程语言,其中 C# 最为常用。本文介绍 C# 在 Unity 中的应用,涵盖脚本生命周期、常用函数、事件处理及面向对象编程等核心概念。通过具体示例,展示如何编写有效的 C# 脚本,包括 Start、Update 和 LateUpdate 等生命周期方法,以及碰撞检测和类继承等高级技巧,帮助开发者掌握 Unity 脚本编程基础,提升游戏开发效率。
83 0
|
3月前
|
C# 图形学 数据安全/隐私保护
Unity数据加密☀️ 二、使用Rider将C#代码生成DLL文件
Unity数据加密☀️ 二、使用Rider将C#代码生成DLL文件
|
5月前
|
C# 图形学 C++
使用vscode开发C#+unity没有代码提示问题
使用vscode开发C#+unity没有代码提示问题
84 0
使用vscode开发C#+unity没有代码提示问题
|
5月前
|
JavaScript 前端开发 C#
初识Unity——创建代码、场景以及五个常用面板(创建C#代码、打开代码文件、场景的创建、Project、Hierarchy、Inspector、Scene、Game )
初识Unity——创建代码、场景以及五个常用面板(创建C#代码、打开代码文件、场景的创建、Project、Hierarchy、Inspector、Scene、Game )
331 0
|
6月前
|
图形学
【Unity C#_菜单Window开发系列_Inspector Component UnityEditor开发】
【Unity C#_菜单Window开发系列_Inspector Component UnityEditor开发】
|
6月前
|
定位技术 C# 图形学
Unity和C#游戏编程入门:创建迷宫小球游戏示例
Unity和C#游戏编程入门:创建迷宫小球游戏示例
154 2