Unity3D中使用委托和事件

摘要:
在Unity3D中,委托和事件c#语言规范用于读取目录1。c#中的委托和事件介绍。方法的参数是方法前言:我一直想写一些与代码设计相关的东西。我之前在做2DX的时候就有了写观察者设计模式的想法,但没有太多实践。现在,我们已经进入了U3D的怀抱,但我们已经学到了很多关于委托事件写作的知识。让我们在这里总结一下。当然,如果我们想特定于Unity3d,我们仍然需要以U3d格式编写。
Unity3D中使用委托和事件
 

前言:

本来早就想写写和代码设计相关的东西了,以前做2DX的时候就有过写写观察者设计模式的想法,但是实践不多。现在转到U3D的怀抱中,倒是接触了不少委托事件的写法,那干脆就在此总结一下吧。

1.C#中的委托、事件引入

本想去找一些高端的介绍来开场,但是找来找去感觉还是用百度百科中的例子来开场也是蛮适合的。当然要具体到Unity3d,我们还是要按照U3d的格式来写。

首先我们来看百度百科这个例子写的是什么?

ok,原来是全球化形势下,不同语种的小伙伴们问候早安时候的一个情景。那么最直观的做法,无非是判断哪国人,然后说英语的调用说英语的方法,说中文的调用说中文的方法,之后再有说日语的,说法语的还要再调用说日语的,说法语的方法。这样做当然OK,但是拓展性很差。

首先是不考虑使用委托时的写法

using UnityEngine;
using System.Collections;
 
public class delegateFanyoy : MonoBehaviour {
 
// Use this for initialization
public UIButton testBtn;
void Start () {
EventDelegate.Add (this.testBtn.onClick, this.BtnClick);
}
public void BtnClick()
{
GoodMoring ("chenjd");
}
 
public void GoodMoring(string name)
{
Debug.Log ("GoodMoring " + name);
}
// Update is called once per frame
void Update () {
 
}
}

  很简单,首先利用EventDelegate为按钮的OnClick事件绑定一个方法,用来测试我们上面提到的问早安的功能。

结果如下:

Unity3D中使用委托和事件第1张

那么问题来了,小匹夫可是堂堂中国人啊,怎么能不说中文反而天天鼓捣英语呢?所以刚刚实现问早的方法GoodMoring()就不能用咯,还要新写一个方法,要输出中文早安,然后再和点击按钮的事件绑定。这样是不是很麻烦呢?

如果有小伙伴觉得不麻烦,那小匹夫只能演示一种小匹夫认为不使用委托的前提下最直接的一种写法了。这时候,GoodMoring就需要改一改了,肯定要根据不同的人来选择不同的问候语咯。这里为了方便,定义一个枚举Language作为判断的依据:

using UnityEngine;
using System.Collections;
 
public class delegateFanyoy : MonoBehaviour {
 
// Use this for initialization
public UIButton testBtn;
void Start () {
EventDelegate.Add (this.testBtn.onClick, this.BtnClick);
}
public void BtnClick()
{
GoodMoring ("chenjd", Language.Chinese);
}
 
public void GoodMoring(string name, Language l)
{
switch (l)
{
case Language.Chinese:
MoringChinese(name);
break;
case Language.English:
MoringEnglish(name);
break;
}
}
 
public void MoringChinese(string n)
{
Debug.Log ("早上好 " + n);
}
 
public void MoringEnglish(string n)
{
Debug.Log ("goodmoring" + n);
}
 
public enum Language
{
Chinese,
English
}
// Update is called once per frame
void Update () {
 
}
}

如果再来一个日语普通话的小伙伴,或者再来一个韩语思密达的小伙伴,那么不可避免我们需要去修改GoodMoring这个函数去实现判断并调用正确的语言输出方法。这样拓展性体现在哪里呢?

如果说能有一个方法A,它的参数也是一个方法B,那么我们保留那个方法A而只需要传入不同的参数(方法B),不就可以灵活的应对了吗?再来一个日本人,一个韩国人,无非只是将说日语和说韩语的方法B传入到那个无需改动的方法A中就可以了,点击按钮触发的事件只需要方法A响应就可以咯。这里方法A就是我们的GoodMoring方法,而方法B作为参数是不同语言的MoringXXXX方法。

那么我们就可以引入代理的概念了。嗯,是那句很老套的——方法的参数是方法。

2.方法的参数是方法

那么我们开始进行第一步分析,千里之行始于足下嘛。

既然方法A的某个参数是方法B,我们所要利用的无非就是使用传入的方法B。所以我们之前的方法A--GoodMoring(string name, language l)方法就变成了

GoodMoring(string name, XXX MoringLanguage)
{
MoringLanguage(name);
}

直接调用作为参数传入的方法。  

但是这里又有新的问题出现了,涉及到要将方法作为参数传入另一个方法,我们都知道,参数的传入是需要有类型的呀。你MoringLanguage到底是个啥?

这里我们似乎又想到了,区分方法,无非是它的返回值,和传入参数类型个数。想到这里,豁然开朗,只要我们规定了传入的MoringLanguage的返回类型和MoringLanguage的参数类型是不是就可以证明传入的MoringLanguage的身份了呢?对!这就是代理了delegate了。

那我们按照MoringChinese和MoringEnglish的返回类型和参数类型来定义这个委托。

1
publicdelegatevoidMoringDelegate(stringname);

那么我们将GoodMoring的修改为

1
2
3
4
GoodMoring(stringname, MoringDelegate MoringLanguage)
{
MoringLanguage(name);
}

就可以了。下面上代码。

using UnityEngine;
using System.Collections;
 
public class delegateFanyoy : MonoBehaviour {
 
// Use this for initialization
public UIButton testBtn;
void Start () {
EventDelegate.Add (this.testBtn.onClick, this.BtnClick);
}
public void BtnClick()
{
GoodMoring ("chenjd", MoringEnglish);
GoodMoring ("小匹夫", MoringChinese);
 
}
 
public void GoodMoring(string name, MoringDelegate MoringLanguage)
{
MoringLanguage (name);
}<br>
public delegate void MoringDelegate(string n);
 
public void MoringChinese(string n)
{
Debug.Log ("早上好 " + n);
}
 
public void MoringEnglish(string n)
{
Debug.Log ("goodmoring" + n);
}
 
public enum Language
{
Chinese,
English
}
// Update is called once per frame
void Update () {
 
}
}

  

Unity3D中使用委托和事件第2张

最后,做个小结,也用一句在网上烂大街的话好了。所谓委托就是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If … Else(Switch)语句,同时使得程序具有更好的可扩展性哟。

装模作样的声明一下:本博文章若非特殊注明皆为原创,若需转载请保留原文链接及作者信息慕容小匹夫

免责声明:文章转载自《Unity3D中使用委托和事件》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇postgresql-锁相关OC常用数据类型大全解下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Hibernate 入门

Hibernate  入门 1. 什么是hibernate ORM框架/持久层框架 jdbc的一个框架 object reference mapping 通过管理对象来改变数据库中的数据 通过管理对象来操作数据库 mybatis 优势:跨数据库的无缝移植 2. 如何在项目中添加hibernate支持(手动添加) 在pom.xml添加hibernate相关...

在线HTML编辑器使用入门(Kindeditor)

 官网: http://kindeditor.net/demo.php   解压,开发中只需要导入选中的文件(通常在 webapp 下,建立 editor 文件夹 )    在使用 kindeditor 页面 导入   <!--导入在线HTML编辑器 --> <script type="text/javascript" sr...

Unity 修改windows窗口的标题

修改windows窗口的标题名称,就是修改下图的东西:  第一种: using UnityEngine; using System; using System.Runtime.InteropServices; public class SetWindowText : MonoBehaviour { #region WIN32API del...

unity3d开发环境配置

1. 首先先下载软件包:http://pan.baidu.com/s/1imYVv  4.2版本2.下载完后,解压会看到两个文件(运行第二个安装包) 3.准备安装,这里直接上图了。 这里全选,里面包括运行媒体之类的。 这里自己选择安装目录。如果你C盘空间不够,可以选择其他盘 开始安装了,等待几分钟 安装成功,去掉勾选Run暂时不需要启动。   ...

springboot SFTP 文件上传下载功能

新增sftp.properies 文件保存 sftp服务器信息 # 协议 sftp.client.protocol=sftp # ip地址 sftp.client.host=改成自己的文件服务器地址 # 端口 sftp.client.port=22 # 用户名 sftp.client.username=root # 密码 sftp.client.passw...

JAVA基础4---序列化和反序列化深入整理(JDK序列化)

一、什么是序列化和反序列化? 序列化:将对象状态信息转化成可以存储或传输的形式的过程(Java中就是将对象转化成字节序列的过程) 反序列化:从存储文件中恢复对象的过程(Java中就是通过字节序列转化成对象的过程) 二、为什么要序列化和反序列化? Java中对象都是存储在内存中,准确地说是JVM的堆或栈内存中,可以各个线程之间进行对象传输,但是无法在进程之间...