前言:

本来早就想写写和代码设计相关的东西了,以前做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事件绑定一个方法,用来测试我们上面提到的问早安的功能。

结果如下:

那么问题来了,小匹夫可是堂堂中国人啊,怎么能不说中文反而天天鼓捣英语呢?所以刚刚实现问早的方法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的返回类型和参数类型来定义这个委托。

public delegate void MoringDelegate(string name);

那么我们将GoodMoring的修改为

GoodMoring(string name, 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);
}
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 () { }
}

  

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

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

Unity3D中使用委托和事件的更多相关文章

  1. 【详细】【转】C#中理解委托和事件 事件的本质其实就是委托 RabbitMQ英汉互翼(一),RabbitMQ, RabbitMQ教程, RabbitMQ入门

    [详细][转]C#中理解委托和事件   文章是很基础,但很实用,看了这篇文章,让我一下回到了2016年刚刚学委托的时候,故转之! 1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托 ...

  2. 【详细】【转】C#中理解委托和事件

    文章是很基础,但很实用,看了这篇文章,让我一下回到了2016年刚刚学委托的时候,故转之! 1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托是C#中类型安全的,可以订阅一个或多个具 ...

  3. unity3d 中动画的帧事件

    代码事件监听 using UnityEngine; using System.Collections; public class BoxEventScript : MonoBehaviour { vo ...

  4. .NET面试题系列[7] - 委托与事件

    委托和事件 委托在C#中具有无比重要的地位. C#中的委托可以说俯拾即是,从LINQ中的lambda表达式到(包括但不限于)winform,wpf中的各种事件都有着委托的身影.C#中如果没有了事件,那 ...

  5. C#委托与事件

    一.在控制台下使用委托和事件 我们都知道,C#中有"接口"这个概念,所谓的"接口"就是定义一套标准,然后由实现类来具体实现其中的方法,所以说"接口,是 ...

  6. C#一些知识点:委托和事件的区别

    在C#中,委托和事件是比较容易混淆的两个知识点,本篇博客就记录一下委托和事件之间的区别. 定义上的区别 委托:委托实际上是一个类,用来表示一个函数,可以理解为C++中的函数指针. 事件:事件是一个修饰 ...

  7. .Net之美读书系列(一):委托与事件

    开启新的读书之旅,这次读的书为<.Net之美:.Net关键技术深入解析>. 我是选择性阅读的,把一些自己觉得容易忘记的,或者比较重要的知识点记录下来,以便以后能方便呢查阅. 尊重书本原作者 ...

  8. 再谈C#委托与事件

    之前写过一篇关于C#委托与事件的文章(见<C#委托和事件例析>),不过还是收到一些网友的提问.所以,今天再换另一个角度来详解一下这个问题. 一.在控制台下使用委托和事件 我们都知道,C#中 ...

  9. c#中委托和事件(续)(转)

    本文将讨论委托和事件一些更为细节的问题,包括一些大家常问到的问题,以及事件访问器.异常处理.超时处理和异步方法调用等内容. 为什么要使用事件而不是委托变量? 在 C#中的委托和事件 中,我提出了两个为 ...

随机推荐

  1. setAttribute()

    ●节点分为不同的类型:元素节点.属性节点和文本节点等.   ●getElementById()方法将返回一个对象,该对象对应着文档里的一个特定的元素节点.   ●getElementsByTagNam ...

  2. django server之间通过remote user 相互调用

    首先,场景是这样的:存在两个django web应用,并且两个应用存在一定的联系.某些情况下彼此需要获取对方的数据. 但是我们的应用肯经都会有对应的鉴权机制.不会让人家随随便便就访问的对吧.好比上车要 ...

  3. 【原】AFNetworking源码阅读(四)

    [原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...

  4. Windows 常用运行库下载 (DirectX、VC++、.Net Framework等)

    经常听到有朋友抱怨他的电脑运行软件或者游戏时提示缺少什么 d3dx9_xx.dll 或 msvcp71.dll.msvcr71.dll又或者是 .Net Framework 初始化之类的错误而无法正常 ...

  5. OpenCV模板匹配算法详解

    1 理论介绍 模板匹配是在一幅图像中寻找一个特定目标的方法之一,这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否“相似”,当相似度足够高时,就认为找到了我们的目标.OpenCV ...

  6. 讓TQ2440也用上設備樹(1)

    作者:彭東林 郵箱:pengdonglin137@163.com QQ:405728433 開發板 TQ2440 + 64MB 內存 + 256MB Nand 軟件 Linux: Linux-4.9 ...

  7. 【Big Data】HADOOP集群的配置(一)

    Hadoop集群的配置(一) 摘要: hadoop集群配置系列文档,是笔者在实验室真机环境实验后整理而得.以便随后工作所需,做以知识整理,另则与博客园朋友分享实验成果,因为笔者在学习初期,也遇到不少问 ...

  8. iOS有关横向TableView的东西

    之前看到Apple store里面有横向的tableview,当然也有可能是collectionview啦. 尤其是项目中只有一条那么需要横向滑动的东西,就没有必要使用庞大的collectionvie ...

  9. Autofac - 属性注入

    属性注入不同于通过构造函数方式传入参数. 这里是通过注入的方式, 在类创建完毕之后, 资源释放之前, 给属性赋值. 这里, 我重新弄一些类来演示这一篇吧. public class ClassA { ...

  10. 使用Expression实现数据的任意字段过滤(1)

    在项目常常要和数据表格打交道. 现在BS的通常做法都是前端用一个js的Grid控件, 然后通过ajax的方式从后台加载数据, 然后将数据和Grid绑定. 数据往往不是一页可以显示完的, 所以要加分页: ...