unity学习-委托(delegate),事件(event),Action,Func

2023-10-29


在进行项目的过程中,一直存在着对代码管理不当的问题,所以需要学习一些科学的代码思维,减少后期功能的修改与迭代引发的代码冗杂和内存爆炸
可以看b站这个大神的视频,讲的可以说无敌详细了,详细到萌新第一次接触会被劝退的地步(可能只是对我)
在这里插入图片描述

委托

含义

根据我观看视频和实际手操后,感觉和java里的接口有点类似,就是这个委托他啥也不干,就是一个指明方向的东东,也有点像指针(没接触过,但是有了解过),感觉就是通过他去找到另一个东东,然后调用他的方法。这么做的好处就是减少代码量,也可以提高代码的可读性和复用性。像java的接口就是只定义方法名,然后剩下的就是去实现这个接口,并且重写他。大概意思好像就是这样,看上面这个大佬的视频他在讲解的时候翻看官方文档,里面说明的时候就说委托他是一个引用类型的数据类型,也相当于Java里自定义一个对象,然后在对象里设置属性,通过新建这个对象设置他的属性,也通过这个对象获得他储存的属性数据。我们自定义的对象就是一个引用类型的数据类型,他在运行的时候只是充当一个地址和路标的作用,实际上不储存任何数据,我们是通过他记录的地址信息,去找到真实的数据,这可能要涉及到堆栈,一个负责存放真实的数据,一个负责存放引用数据的地址。这是我看后的感觉,如果有不对的地方,欢迎大佬们指正!

定义

如何在代码中声明一个委托,只要像创建方法一个就行,在前面加多一个delegate即可

public delegate void TestDelegate();

这是自定义的委托,c#里有自带的Action 和 Func委托类
第一个是可以传入参数,但不给返回值的委托
第二个是有返回值,也可以传入参数的委托
查看他们的类,你也能看到他们其实也是自己在创建的时候添加了delegate这个属性来定义他是一个委托的

使用

当存在传入参数类型和数量一致,并且返回值类型也保持一致的多个方法的时候,可以统一用委托进行调用,提高代码的可用性,并且如果在这多个方法中如果大致相同,只是部分参数的不同,那个参数也可以使用委托代替。
这里只做学习记录,不做过多的代码演示(就是还没学透)

事件

含义

基于委托,通过委托链接事件的拥有者和响应者,分别调用他们各自的办法
相较委托更安全,因为使用事件只能对事件进行添加减少,不能获得其他的方法,防止了数据污染和非法调用,而且通过委托可以对事件响应者要调用的方法进行约束,减少bug出现的频率
一个完整的事件应该包括
事件拥有者,事件,事件响应者,事件处理器以及事件订阅
拥有者就是发送消息的对象,需要在这个对象里写好需要发送的内容并且调用事件,事件就是拥有者需要做的事情,事件响应者就是收到要进行事件的对象,而事件处理器就是响应者收到消息后要做的事情,事件订阅就是将事件拥有者和事件响应者之间进行连接

使用

using UnityEngine;
//先定义一个委托
public delegate void CatCallEventHandle();//这个就是事件订阅需要的条件之一
public class Test : MonoBehaviour
{
	//定义一个猫类
	class Cat{
		//定义一个事件,绑定委托
		public event CatCallEventHandle CatCall;
		//定义猫叫类
		public void OnCall(){
			Debug.Log("CatCall");
			//启动事件,也即是发送消息
			CatCall();
		}
	}
	//定义一个人类
	class People{//事件响应者
		//定义人醒了的方法
		public void PeopleAwake(){//事件处理器
			Debug.Log("人醒了");
		}
	}
	//定义鼠类
	class Mouse{//事件响应者
		public void MouseCall(){//事件处理器
			Debug.Log("鼠叫");
		}
	}
	//创建启动方法
	void Start(){
		Cat cat = new Cat();
		People people = new People();
		Mouse mouse = new Mouse();
		//给事件添加需要发送消息的对象
		cat.CatCall += new CatCallEventHandle(people.PeopleAwake);//将需要调用的方法传给委托
		cat.CatCall += new CatCallEventHandle(mouse.MouseCall);//事件订阅中
		//启动猫叫的方法
		cat.OnCall();
	}
}

运行
在这里插入图片描述
大致的流程就是先创建委托,这个委托的入参和返回都需要提前设计好,后面在发送消息的时候如果事件响应者和委托的入参或者返回值不同都无法正常运行
总结,可能运用时候不会很难,但是原理要搞懂还是需要花时间
后面需要使用事件和委托去实现任务系统。加油吧~

2022.08.18更新
在这里插入图片描述

上面的代码可以简写成

cat.CatCall += people.PeopleAwake;
cat.CatCall += mouse.MouseCall;

之前那样写是因为视频这么写, 也没有说可以简写,可能是为了更方便我们理解(但其实我反而更不好理解了 …)

总而言之,最近又重温了一遍这四个关键词,下面是我的个人感受
推荐一个视频,这个视频讲的真的很容易理解

https://www.bilibili.com/video/BV1LT411L7yv?spm_id_from=333.788.top_right_bar_window_history.content.click&vd_source=a9f1c2747f921195810879a90b078430

delegate用法: delegate void 委托名(形参); -----委托可以看做是类
委托名 方法名

event用法; 可以看成和void一样的存在------限制不让委托的方法被外部类清空(重点是不让外界=,也不允许在外部类执行,但是可以+=和-=,+=和-=的范围没有限制,其实个人感觉这样好像还是可以污染委托…)

Actino用法:Action<参数类型> 名称;

Func用法:Func<参数类型,返回值> 名称; ----<>里最后一个参数作为返回值

以上的委托事件等用法都必须保证里面不为空,再去执行,否则会报错!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

unity学习-委托(delegate),事件(event),Action,Func 的相关文章

  • 如何在 Visual Studio 2010 中增强 XAML 设计器?

    当我使用 XAML 设计器时 进入设计器和退出设计器是如此困难和缓慢 当我这样做时 Visual Studio 卡了一段时间 有什么方法可以增强 XAML 设计器和编辑器吗 Ant 保存 XAML 文件时非常慢 这通常意味着您可能有复杂的
  • 用 C++ 进行服装建模 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在编写一些软件 最终会绘制一个人体框架 可以配置各种参数 并且计划是在假人身上放置某种衣服 我研究
  • 在 C# 中创建具有单独列的分隔文本

    我一直在尝试在 C 中创建一个制表符限制的文本文件 以便数据正确显示在单独的列中 Firstname Lastname Age John Smith 17 James Sawyer 31 我尝试过 t 字符 但我得到的只是 Firstnam
  • 如何使用MemoryCache代替Timer来触发一个方法?

    以下方法通过等待已运行操作的结果来处理并发请求 对数据的请求可能会使用相同 不同的凭据同时出现 对于每组唯一的凭据 最多可以有一个GetCurrentInternal呼叫正在进行中 当准备就绪时 该呼叫的结果将返回给所有排队的服务员 pri
  • 使用Physics.Raycast 和Physics2D.Raycast 检测对象上的点击

    我的场景中有一个空的游戏对象 带有 2D 组件盒碰撞器 我将脚本附加到该游戏对象 void OnMouseDown Debug Log clic 但是当我点击我的游戏对象时 没有任何效果 你有什么想法 如何检测我的盒子碰撞器上的点击 使用光
  • C++ 中本地类中的静态成员变量?

    我知道我们不能宣布static本地类中的成员变量 但其原因尚不清楚 那么请问有人可以解释一下吗 另外 为什么我们不能访问非static函数内部定义的变量 内部已经定义了局部类 直接在局部类成员函数中 在下面给出的代码中 int main i
  • 如何将 #ifdef DEBUG 添加到 Xcode?

    我的项目中有一些代码永远不应该在发布版本中使用 但在测试时很有用 我想做这样的事情 ifdef DEBUG Run my debugging only code endif 在 Xcode 4 中哪里添加 DEBUG 设置 我尝试将其放入
  • 如何访问另一个窗体上的ListView控件

    当单击与 ListView 所在表单不同的表单中的按钮时 我试图填充 ListView 我在 Form1 中创建了一个方法以在 Form2 中使用 并将参数传递给 Form1 中的方法 然后填充 ListView 当我调试时 我得到了传递的
  • C# Dns.GetHostEntry 不返回连接到 WiFi 的移动设备的名称

    我有一个 C 中的 Windows 窗体应用程序 我试图获取列表中所有客户端的主机名 下面给出的是 ra00l 来自此链接的代码示例 GetHostEntry 非常慢 https stackoverflow com questions 99
  • 无法在 Windows 运行时组件库的 UserControl 中创建依赖项属性

    我想在用户控件内创建数据可绑定属性 这个用户控件包含一个 Windows 运行时组件 项目 我使用下面的代码来创建属性 public MyItem CurrentItem get return MyItem GetValue Current
  • 如何在 C# 中定义文本框数组?

    您好 当我在 Windows 申请表上创建文本框时 我无法将其命名为 box 0 box 1 等 我这样做的目的是因为我想循环使用它们 其实我发现TextBox array firstTextBox secondTextBox 也有效
  • 获取 WPF 控件的所有附加事件处理程序

    我正在开发一个应用程序 在其中动态分配按钮的事件 现在的问题是 我希望获取按钮单击事件的所有事件 因为我希望删除以前的处理程序 我尝试将事件处理程序设置为 null 如下所示 Button Click null 但是我收到了一个无法分配 n
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • 如何在 Linq 中获得左外连接?

    我的数据库中有两个表 如下所示 顾客 C ID city 1 Dhaka 2 New york 3 London 个人信息 P ID C ID Field value 1 1 First Name Nasir 2 1 Last Name U
  • 未经许可更改内存值

    我有一个二维数组 当我第一次打印数组的数据时 日期打印正确 但其他时候 array last i 的数据从 i 0 到 last 1 显然是一个逻辑错误 但我不明白原因 因为我复制并粘贴了 for 语句 那么 C 更改数据吗 I use g
  • 批量更新 SQL Server C#

    我有一个 270k 行的数据库 带有主键mid和一个名为value 我有一个包含中值和值的文本文件 现在我想更新表格 以便将每个值分配给正确的中间值 我当前的方法是从 C 读取文本文件 并为我读取的每一行更新表中的一行 必须有更快的方法来做
  • 如何在 Blackberry Cascades 中显示具有特定号码的电话板

    我正在使用带有 C QT 和 QML 的 Blackberry Cascades 10 Beta 3 SDK 以及 Blackberry 10 Dev Alpha Simulator 和 QNX Momentics IDE 并且我正在尝试实
  • 如何在按钮单击时模拟按键 - Unity

    我对 Unity 中的脚本编写非常陌生 我正在尝试创建一个按钮 一旦单击它就需要模拟按下 F 键 要拾取一个项目 这是我当前的代码 在编写此代码之前我浏览了所有统一论坛 但找不到任何有效的东西 Code using System Colle
  • 编译时“strlen()”有效吗?

    有时需要将字符串的长度与常量进行比较 例如 if line length gt 2 Do something 但我试图避免在代码中使用 魔法 常量 通常我使用这样的代码 if line length gt strlen Do somethi
  • 检查Windows控制台中是否按下了键[重复]

    这个问题在这里已经有答案了 可能的重复 C 控制台键盘事件 https stackoverflow com questions 2067893 c console keyboard events 我希望 Windows 控制台程序在按下某个

随机推荐

  • HTTP协议系列教材 (二)- 借助FireFox火狐调试工具学习HTTP协议 

    对于HTTP协议的学习 我们将借助火狐浏览器FIREFOX的调试工具来实际观察浏览器和服务器之间传输数据的具体内容 步骤1 下载 FireFox步骤2 打开调试工具步骤3 观察 request response 步骤 1 下载 FireFo
  • 解决Jmeter返回数据中文乱码问题

    步骤1 修改jmeter中的配置文件jmeter properties的配置项sampleresult default encoding 修改为utf 8 解除注释后重启Jmeter 步骤2 添加后置处理器 BeanShell PostPr
  • 跟我学Java设计模式第三天:代理模式、适配器、装饰者等其中模式结构

    5 结构型模式 结构型模式描述如何将类或对象按某种布局组成更大的结构 它分为类结构型模式和对象结构型模式 前者采用继承机制来组织接口和类 后者釆用组合或聚合来组合对象 由于组合关系或聚合关系比继承关系耦合度低 满足 合成复用原则 所以对象结
  • Java实现自定义注解

    前言 1 Java实现自定义注解其实很简单 跟类定义差不多 只是属性的定义可能跟我们平时定义的属性略有不同 这里会给大家详解 先来看代码 Target ElementType FIELD Retention RetentionPolicy
  • C++使用string的大数运算(4)除法

    本次项目目标 使用C 完成对于大数的相关运算 项目要点 1 大数指的是远超long long int的数据 2 将大数用矩阵进行存储 并通过矩阵实现运算 3 本人采用字符串进行存储 应注意char的特点 比如 char a 161 cout
  • OpenErp的权限

    首先引用一篇入门文章 http www oscg cn openerp develop doc 09 可以发现 其实openerp的权限分成了多层次的 菜单 视图 对象 规则 从字面意思就是每层都控制着自己对应的权限 然后我创建了一个新的g
  • HTML5 canvas 计算文字宽度的方法(measureText)

    var c document getElementById myCanvas var ctx c getContext 2d ctx font 30px Arial var txt Hello World ctx fillText widt
  • IEEE 802.3ad 链路聚合与LACP的简单知识&EtherChannel 总结

    IEEE 802 3ad 链路聚合与LACP的简单知识 内容提要 本文主要介绍了链路聚合的概念以及链路聚合与EtherChannel 以太通道 的区别 说明 IEEE 802 3ad 是执行链路聚合的标准方法 从概念上讲 将多个以太网适配器
  • 国内首个行业级燃机智慧运维云平台是如何炼成的?

    在未来的能源结构转型中 燃气发电将发挥重要作用 这似乎颠覆了人们日常认知 众所周知 在碳达峰 碳中和的环保目标下 我国能源结构正迎来根本性变革 传统化石能源占比将逐步下降 绿色低碳的新能源占比将持续提升 为何还要推动燃气发电的发展 这绝非虚
  • android edittext setonkeylistener,Android EditText 键入事件 —setOnKeyListener

    main xml android orientation vertical android layout width fill parent android layout height fill parent gt android layo
  • Vue简单示例——weex

    weex的生命周期 因为我们的Weex和Vue是绑定在一起的 所以我们讨论关于生命周期时 说的实际上是在Weex中可以使用的Vuex的生命周期 也就是Weex对于Vue生命周期的支持 好消息 Weex支持大部分的Vue中的生命周期钩子函数
  • apple mobile device服务无法启动,错误1053 解决

    本文转载自 https www cnblogs com relax p 3476741 html 作者 relax 转载请注明该声明 我不想安装iTunes 于是下了iTunes64安装包 解压后得到6个文件 安装完 AppleMobile
  • 进程的描述与控制(二)_OS

    目录 1 进程与线程的比较 2 线程的实现方式 内核支持线程 KST 用户级线程 ULT ULT KST 组合方式 3 进程同步的概念 4 两种形式的制约关系 5 临界资源 6 对临界资源访问的过程 7 同步机制应该遵循的规则 8 解决临界
  • 轻松应对IDC机房带宽突然暴涨问题

    轻松应对IDC机房带宽突然暴涨问题 1 提出问题 实际案例一 凌晨3 00点某公司 网站业务 的一个IDC机房带宽流量突然从平时高峰期150M猛增至1000M 如下图 该故障的影响 直接导致数百台服务器无法连接 该机房全部业务中断 实际案例
  • [深度学习实战]基于PyTorch的深度学习实战(下)

    目录 一 前言 二 Mnist手写数字图像识别 2 1 加载数据 2 1 1 下载地址 2 1 2 用 numpy 读取 mnist npz 2 2 定义卷积模型 2 3 开始训练 2 4 完整代码 2 5 验证结果 2 6 修改参数 三
  • vue项目中的路由配置

    公司的项目使用vue脚手架来搭建 是属于后台管理系统 功能页比较多 就使用vue路由来进行跳转 个人比较习惯上面这种方式放置路由文件 并且使用懒加载的模式来配置 如下 import Vue from vue import Router fr
  • qemu 出现Could not access KVM kernel module: No such file or directory failed to initialize KVM: No su...

    使用qemu命令 qemu system x86 64 hda image ubuntu test img cdrom ubuntu 16 04 2 server amd64 iso m 1024 enable kvm boot d 安装u
  • Android终端Termux安装MariaDB/MySQL数据库

    前言 Android移动设备并非设计为服务器 尽管其中一些功能强大 但是 随着技术的进步以及我们可以用手机做更多的事情 总是很有趣的 今天 借助Termux应用程序 我们将了解如何在Android上安装MySQL或MariaDB数据库 为此
  • Linux常用命令学习

    原文转自https www cnblogs com gaojun p 3359355 html 1 ls命令 就是list的缩写 通过ls 命令不仅可以查看linux文件夹包含的文件 而且可以查看文件权限 包括目录 文件夹 文件权限 查看目
  • unity学习-委托(delegate),事件(event),Action,Func

    unity学习 委托 含义 定义 使用 事件 含义 使用 在进行项目的过程中 一直存在着对代码管理不当的问题 所以需要学习一些科学的代码思维 减少后期功能的修改与迭代引发的代码冗杂和内存爆炸 可以看b站这个大神的视频 讲的可以说无敌详细了