一.什么是委托

1.委托的概述

为了实现方法的参数化,提出了委托的概念。委托是一种类是一种引用类型,可以指向一个或者多个方法,该引用类型与其他引用类型不同。在委托对象的引用中存放的不是数据的引用,而是对方法的引用,即在委托的内部包含一个指向某个方法的指针。通过使用委托把方法的引用封装在委托对象中,然后将传递的给调用的引用方法的代码。这个委托类型的实例,可以和任何其他方法相关联起来,储存这些方法的引用只要类型兼容(类型兼容即任何方法他们的参数和返回值与委托的参数和返回值保持一致)。委托也是事件的本质,事件也是委托类型字段的包装器。

1.现实世界举例

拿现实世界举例子比如你在宿舍微信群发出,出去买饭快了回来的消息,而你的舍友们想要让你带饭,这就是一种委托。简而言之委托就是有一件事我不亲自做它,而是交给别人替我去做那些本该由我来做的事。我委托你干什么你就干什么,没有委托你你概不负责。

2.程序世界举例

拿游戏开发举例子,游戏结束你写了一个GameOver的方法你想让游戏结束后想让这个方法里实现些什么比如Player的经验增加,播放胜利动画,显示结束UI等功能。这个时候就可以通过委托的方法,定义一个委托类型Mydelegate通过Mydelegate订阅封装Player的经验增加,播放胜利动画,显示结束UI这几个方法,然后GameOver()直接调用Mydelegate();就好了直接实现了这3个功能,所以GameOver()可以不用直接调用这3个方法,可以通过委托间接调用

二.代码举例

此例子讲的是一个图片,通过按空格键实现此图片的颜色随机变化,位置随机变化,打印当前时间的3个功能。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;//public delegate void Mydelegate();//保持类与类的平级关系public class Main : MonoBehaviour
{//声明委托类型public delegate void Mydelegate();//该委托类型可以指向任何一个返回值为空,参数列表为空的其他方法。//声明格式为:访问修饰符,  delegate ,与目标方法一致的返回值类型,委托名称,,与目标方法一致参数列表//【嵌套类型】Mydelegate mydelegate;private SpriteRenderer sp;private void OnEnable(){mydelegate = new Mydelegate(Teleport);//完整订阅格式mydelegate +=ChangeColor;//直接让变量引用方法mydelegate += log;//切记:只有第一个可以使赋值操作,之后的订阅必须是+=,不然的话之后的订阅会覆盖之前的赋值操作**//如果这个是=号他只会引用log,teleport就会被覆盖}void Start(){sp = GetComponent<SpriteRenderer>();}void Update(){if (Input.GetKeyDown(KeyCode.Space)){//    Teleport();//直接调用//    ChangeColor();//直接调用//    log();//直接调用mydelegate();//在update调用mydelegate,间接调用3个方法// mydelegate.Invoke();//可以用Invoke()调用          }}//随机更换位置private void Teleport(){sp.color = new Color(UnityEngine.Random.value, UnityEngine.Random.value, UnityEngine.Random.value);}//切换颜色private void ChangeColor(){Vector2 currentpos = transform.position;currentpos.x = UnityEngine.Random.Range(-5f, 5f);transform.position = currentpos;}//打印当前时间private void log(){Debug.Log("Current Time is:" + DateTime.Now);}}

该代码的流程是
1.首先声明一个委托类型。
2.再声明一个委托类型的字段。
3.分别写好实现三个功能的方法。
4.在OnEnable()中实现委托的订阅(+=)直接让变量引用方法。
5.在Update()中调用订阅之后委托类型字段。
下面依次介绍主要步骤

三.委托的语法

1.声明格式

public delegate void Mydelegate();
//该委托类型可以指向任何一个返回值为空,参数列表为空的其他方法。

委托的声明和普通的类有一定区别,但跟方法确有些相似
声明格式为:访问修饰符, delegate ,与目标方法(所引用的方法)一致的返回值类型,委托名称,与目标方法一致参数列表

2.委托的订阅

1.单播委托

一个委托封装了一个方法的形式叫做【单播委托】

private void OnEnable(){mydelegate = new Mydelegate(Teleport);//完整订阅格式//mydelegate = Teleport;//简介订阅方式}

如图所示这个委托只封装了随机更换位置这一个方法,所以这就是单播委托
可以用=号进行赋值操作,也可以用+=订阅。

2.多播委托

一个委托封装的多个方法的使用形式叫做【多播委托】

private void OnEnable(){mydelegate = new Mydelegate(Teleport);//完整订阅格式mydelegate += ChangeColor;//直接让变量引用方法mydelegate += log;//切记:只有第一个可以使赋值操作,之后的订阅必须是+=,不然的话之后的订阅会覆盖之前的赋值操作//如果这个是=号他只会引用log,teleport就会被覆盖}

如图所示
1.多播委托就是我的变量订阅了多个方法,切记只有第一个可以使赋值操作,之后的订阅必须是+=,不然的话之后的订阅会覆盖之前的赋值操作,如果这个是=号他只会引用log,teleport就会被覆盖。
2.由于我声明的是无返回值,无参数列表的委托,所以我的委托只能订阅无返回值,无参数列表的方法,这就是类型兼容。

3.简单例子

解释都在注释中

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;public class delegate01 : MonoBehaviour
{public delegate int  Mydelegate_01(int n1, int n2);//该委托类型可以指向任何一个返回值为int类型,参数列表为两个int类型参数的其他方法。Mydelegate_01 mydelegate_01;private void OnEnable(){mydelegate_01 = Add;//订阅ADD方法mydelegate_01 += Mutiply;//订阅Mutiply方法//切记ADD 和 Mutiply也是返回值为int类型,参数列表为两个int类型参数的方法,保持类型兼容}void Update(){if (Input.GetKeyDown(KeyCode.Space)){Debug.Log(mydelegate_01(2, 3));}}public int Add(int a, int b){Debug.Log(a + b);return a + b;}public int Mutiply(int  a,int  b){Debug.Log(a * b);return a * b;}}

四.Func<>委托和Action<>委托

Func<>委托和Action<>委托的本质其实还是Delegate,与Delegate的使用方法如出一辙

1.Func<>委托

1.Func<>一定能指向一个有返回值,可以有参数列表的方法(参数列表可以没有,但返回值必须有)
2.定义格式:例如Func<参数,参数,返回值类型> 括号的最后一个值永远是返回值(参数可以是多个,最多是16个跟Action相同。

举例

解释见注释

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;public class delegate01 : MonoBehaviour
{Func<int, int, int> func;//能指向一个返回值为int,和两个类型为int的参数的方法private void OnEnable(){func += Add;//订阅func += Mutiply;}void Update(){if (Input.GetKeyDown(KeyCode.Space)){Debug.Log( func(2,3));}}public int Add(int a, int b)//与func类型兼容的方法{Debug.Log(a + b);return a + b;}public int Mutiply(int  a,int  b)//与func类型兼容的方法{Debug.Log(a * b);return a * b;}}

2.Action<>委托

1.Action<>委托一定指向一个无返回值的方法,参数可有可无。
2.定义:因为Action没有返回值,所以括号里全是参数(也可以没有尖括号那就代表着没有参数)
Action action/Action<参数> action

举例

using System.Collections.Generic;
using UnityEngine;
using System;public class delegate01 : MonoBehaviour
{Action<string> action;//能指向一个无返回值,和一个String类型的方法private void OnEnable(){action = SayHello;}void Update(){if (Input.GetKeyDown(KeyCode.Space)){          action.Invoke("Ben");}}public void SayHello(string name){Debug.Log("Hello~" + name);}
}

五.常用用法

1.由于为了实现方法的参数化,提出了委托的概念,所以要将委托作为参数传递到方法中。所以引出了常用的作为模板方法和回调方法来使用。

1.模板方法

1.有一处不确定,其余代码都是固定写好的,这个不确定的部分(参数)就是靠我们传进来的委托类型
的参数所包含的方法来填补,就跟填空题一样。由于这个方法一般需要返回值,所以一般都用Func委托作为模板方法。

举例

描述:这个例子是为了实现输出玩家的夺旗数,死亡数和击杀数最高的玩家名称
1.首先这是玩家的基本信息类 里面包括了击杀数,夺旗数和死亡数的字段

2.第二部我们声明一个返回值为int类型,为PlayerStatus类型的,int类型返回值用于返回我们玩家击杀数等信息

3.创建以我们创建委托类型为参数的方法(string返回值用于返回玩家的名称),为什么种方法呢,因为这里的不确定的部分就是int tempnum = _delegate(player),通过该委托封装的方法返回的int值来代替int tempnum =,的后面的内容将player作为delegate的参数,然后进行下面的判断,


4.创建与委托类型兼容的方法,也就是返回击杀数等数值的方法,然后我们就可以将与委托类型类型兼容的方法来代替这个委托类型的参数(其实省略了创建委托字段,订阅方法的这两个步骤,直接代替即可)


5.补充:其实也可以用LAMBDA表达式匿名函数的方法来代替直接用方法代替参数的方法。这样的话直接省略了创建类型兼容方法的这步,减少了代码量。
LAMBDA表达式:(输入参数的参数名字)=>输出return 输出数值

6.利用这种委托最为参数的方法,来避免了如果计算更多的值,还得写更多的判断方法。减少了代码量。

2.回调方法

1.以回调方法的形式使用委托,根据逻辑,动态选择是否调用

举例

解释:该方法的参数有一个返回值为Product类型的Fuc<>委托和一个参数为Product类型的Action<>委托,将func委托的返回值赋给box.Product,如果func()的返回值的Price大于了5则将func返回的Product类型返回值,作为Action委托的参数使用。那如果func()的返回值的Price不大于5,那么永远也不会调用Action委托所以Action是通过内部逻辑才会调用的,所以这里的Action委托所封装的方法是作为回调方法使用的,则Func委托所封装的方法是作为模板方法使用的。

Unity游戏开发(C#语法):委托相关推荐

  1. unity ui 补间动画_杭州Unity游戏开发培训内容有哪些?学习路线是如何规划的?...

    现在Unity游戏开发行业越来越受到欢迎,但是想要找到适合自己的课程和学习方法却有些困难.很多刚开始接触Unity游戏开发且没有基础的同学,不知道该从哪里开始学,也不知道要学习什么内容.该怎么开始Un ...

  2. 最全面的Unity游戏开发指南视频教程 第2卷

    最全面的Unity游戏开发指南视频教程 第2卷 流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小 ...

  3. Unity游戏开发视频教程 第2卷

    从完全的初学者到专业的游戏开发者.学习用C#编写代码,用Unity创建令人惊叹的游戏 Unity游戏开发视频教程 第2卷 你会学到什么 了解如何编写高级C#代码 学习好的编码原则和设计实践 发展强大的 ...

  4. Unity游戏开发之游戏存档方式

    目录 1.Unity自带存储方式PlayerPrefs 2.XML存储方式 3.Json类型存储方式 1.Unity的序列化问题 2.Unity中支持序列化的类 3.Unity中Json的使用方法 4 ...

  5. 喵的Unity游戏开发之路 - 对象持久化

    原文: https://mp.weixin.qq.com/s/NNLHFLEBJE_UIksBtDcglA 前言         很多童鞋没有系统的Unity3D游戏开发基础,也不知道从何开始学.为此 ...

  6. 零基础小白如何自学 Unity 游戏开发?(送 Unity 教程)

    如何自学 Unity? 初级阶段:学习编程语言 初级阶段:编程实践 中级阶段:继续学习编程语言 Unity 教程赠书活动 内容简介 作者简介 赠书方式 如何自学 Unity? 有很多同学对 游戏开发 ...

  7. Unity游戏开发大师班

    大小解压后:8.63G 持续时间19h 包含项目文件 1280X720 MP4 语言:英语+中英文字幕(根据原英文字幕机译更准确) Unity游戏开发大师班 信息: 要求 –没有课程要求,展示了开发过 ...

  8. Unity 游戏开发技巧集锦之使用cookie类型的纹理模拟云层的移动

    Unity 游戏开发技巧集锦之使用cookie类型的纹理模拟云层的移动 使用cookie类型的纹理模拟云层的移动 现实生活中,当阳光直射大地,而天空中又有很多云时,云层的影子总是会投射在大地上,风吹着 ...

  9. Unity 游戏开发技巧集锦之创建透明的材质

    Unity 游戏开发技巧集锦之创建透明的材质 Unity创建透明的材质 生活中不乏透明或者半透明的事物.例如,擦的十分干净的玻璃,看起来就是透明的:一些塑料卡片,看起来就是半透明的,如图3-23所示. ...

最新文章

  1. Socket通信之操作系统的字节序和位数
  2. sklearn使用FeatureHasher处理字符串特征
  3. linux 系统 RRDTool安装方法
  4. django learn 多对多的两种映射关系
  5. jenkins~管道Pipeline里使用公用类库
  6. CATALINA_BASE和CATALINA_HOME,多实例tomcat与多版本tomcat运行
  7. mysql5.7.14多实例安装
  8. android 剪贴板管理器,安卓剪贴板管理(Clipper Plus)
  9. 基于Tensorflow实现DeepFM
  10. git安装 苹果笔记本_自己挖的坑自己填,无光驱安装苹果笔记本双系统
  11. Chrome扩展推荐
  12. 为mandriva 2010 spring打包(geany-0.19.2)
  13. 头孢一代比一代强吗?
  14. 小瘦牛虚拟无线路由器官方版
  15. Java——正三角、倒三角、菱形打印
  16. 为树莓派增加MIDI接口
  17. 050002《马云说》读后感——勇者无畏
  18. 博客开张篇 人生的几大境界和追求
  19. 那些年一起追过的日漫之留下的经典台词
  20. 今天主要学习vue的一些原理,尤其是vueComponent与Vue的关系,个人觉得值得反复回味,很巧妙

热门文章

  1. 苹果审核4.3被拒,调查,被封下架,讨论与规避
  2. 如何给WPS里全是图片的word文档中利用题注自动编号
  3. friends迷必须知道的114件事
  4. nginx配置 yii2_Yii2如何应用配置nginx服务器
  5. 对话初链CEO张剑南:未来一切资产皆可链上化
  6. 课设毕设神器,8个经典抢答器优选电路设计方案合辑
  7. 以太坊编程简单介绍 ,Part-1
  8. 你为什么找不到女朋友?
  9. 甜甜C语言—malloc()函数
  10. ubuntu18.04 安装 Kurento