前言:

本来早就想写写和代码设计相关的东西了,以前做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. .NetCore MVC中的路由(1)路由配置基础

    .NetCore MVC中的路由(1)路由配置基础 0x00 路由在MVC中起到的作用 前段时间一直忙于别的事情,终于搞定了继续学习.NetCore.这次学习的主题是MVC中的路由.路由是所有MVC框 ...

  2. Js new到底发生了什么

    在Js中,我们使用了new关键字来进行实例化 那么在这个new的过程中到底发生了什么? 关于构造函数的return 正常来讲构造函数中是不用写return语句的,因为它会默认返回新创建的对象. 但是, ...

  3. kafka学习笔记:知识点整理

    一.为什么需要消息系统 1.解耦: 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束. 2.冗余: 消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险. ...

  4. AJAX操作数据

    本文使用AJAX访问数据库文件,并显示在网页中.另外还有AJAX对数据库的删除操作,网页不加载,只刷新数据. 随意使用数据库中的一张表: 使用AJAX显示表中内容,首先打入body代码: <h1 ...

  5. Syscall,API,ABI

    系统调用(Syscall):Linux2.6之前是使用int0x80(中断)来实现系统调用的,在2.6之后的内核是使用sysentry/sysexit(32位机器)指令来实现的系统调用,这两条指令是C ...

  6. ecshop验证码

    <?php //仿制ecshop验证码(四位大写字母和数字.背景) //处理码值(四位大写字母和数字组成) //所有的可能的字符集合 $chars = 'ABCDEFGHIJKLMNOPQRST ...

  7. 【初码干货】使用阿里云对Web开发中的资源文件进行CDN加速的深入研究和实践

    提示:阅读本文需提前了解的相关知识 1.阿里云(https://www.aliyun.com) 2.阿里云CDN(https://www.aliyun.com/product/cdn) 3.阿里云OS ...

  8. TFS 生成发布代理

    下载Agent 后,执行配置命令     参考 安装TFS(2015)工作组模式代理服务器(Agent)

  9. 第11章 Linux服务管理

    1. 服务分类 (1)Linux的服务 ①Linux中绝大多数的服务都是独立的,直接运行于内存中.当用户访问时,该服务直接响应用户,其好处是服务访问响应速度快.但不利之处是系统中服务越多,消耗的资源越 ...

  10. 基于Node.js实现一个小小的爬虫

    以前一直听说有爬虫这种东西,稍微看了看资料,貌似不是太复杂. 正好了解过node.js,那就基于它来个简单的爬虫. 1.本次爬虫目标: 从拉钩招聘网站中找出“前端开发”这一类岗位的信息,并作相应页面分 ...