前言:

本来早就想写写和代码设计相关的东西了,以前做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. 搞个这样的APP要多久?

    这是一个“如有雷同,纯属巧合”的故事,外加一些废话,大家请勿对号入座.开始了…… 我有些尴尬地拿着水杯,正对面坐着来访的王总,他是在别处打拼的人,这几年据说收获颇丰,见移动互联网如火如荼,自然也想着要 ...

  2. hibernate多对多关联映射

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

  3. .Net多线程编程—预备知识

    1 基本概念 共享内存的多核架构:一个单独的封装包内封装了多个互相连接的未处理器,且所有内核都可以访问主内存.共享内存的多核系统的一些微架构,例如内核暂停功能,超频. 内核暂停功能:当使用内核不多的时 ...

  4. 重撸js_2_基础dom操作

    1.node 方法 返回 含义 nodeName String 获取节点名称 nodeType Number 获取节点类型 nodeValue String 节点的值(注意:文本也是节点) 2.inn ...

  5. ASP.NET Core应用针对静态文件请求的处理[2]: 条件请求与区间请求

    通过调用ApplicationBuilder的扩展方法UseStaticFiles注册的StaticFileMiddleware中间件帮助我们处理针对文件的请求.对于StaticFileMiddlew ...

  6. .NET Core的日志[2]:将日志输出到控制台

    对于一个控制台应用,比如采用控制台应用作为宿主的ASP.NET Core应用,我们可以将记录的日志直接输出到控制台上.针对控制台的Logger是一个类型为ConsoleLogger的对象,Consol ...

  7. Android Studio —— 重装 HAXM

    Android Studio -- 重装 HAXM 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. Android SDK 自带模拟器一直以慢.卡 ...

  8. 从源码浅析MVC的MvcRouteHandler、MvcHandler和MvcHttpHandler

    熟悉WebForm开发的朋友一定都知道,Page类必须实现一个接口,就是IHttpHandler.HttpHandler是一个HTTP请求的真正处理中心,在HttpHandler容器中,ASP.NET ...

  9. WPF 捕获键盘输入事件

    最近修改的一个需求要求捕获键盘输入的 Text,包括各种标点符号. 最开始想到的是 PreviewKeyDown 或者 PreviewKeyUp 这样的键盘事件. 但是这两个事件的对象 KeyEven ...

  10. JQuery中的siblings()是什么意思

    jQuery siblings() 方法返回被选元素的所有同胞元素,并且可以使用可选参数来过滤对同胞元素的搜索. 实例演示:点击某个li标签后将其设置为红色,而其所有同胞元素去除红色样式. 1.创建H ...