当前位置: 首页 > news >正文

【unity小技巧】委托(Delegate)的基础使用和介绍

文章目录

  • 一、前言
    • 1. 什么是委托?
    • 2. 使用委托的优点
  • 二、举例说明
    • 1. 例1
    • 2. 例2
  • 三、案例
  • 四、泛型委托Action和Func
    • 1. Action委托
    • 2. Func委托
  • 五、参考
  • 六、完结

一、前言

1. 什么是委托?

在Unity中,委托(Delegate)是一种用于处理方法回调的特殊类型。它允许您将方法作为参数传递给其他方法,并在需要时调用这些方法。

委托在游戏开发中非常有用,特别是在事件处理、消息传递和异步操作方面。它提供了一种灵活的方式来注册和触发方法,而无需显式地知道这些方法的实现细节。

个人理解:可以把委托理解为一个容器,容器里面放可以放很多函数方法。一调用委托,里面所有的函数方法都会同步被执行

2. 使用委托的优点

使用委托的优点如下:

  1. 解耦性:使用委托可以帮助解耦代码,使得不同部分之间的依赖关系更加松散。通过将方法作为参数传递给委托,可以将方法的调用从直接依赖于特定对象解耦,从而提高代码的灵活性和可维护性。

  2. 可扩展性:使用委托可以轻松地扩展代码功能。您可以通过在不修改现有代码的情况下注册或替换委托方法来添加新的功能或更改现有功能。这使得您可以将委托用于事件处理和插件系统等场景。

  3. 事件驱动:委托在事件驱动的编程中非常有用。您可以使用委托将方法注册为事件的处理程序,当事件发生时,委托会自动调用所有注册的方法。这样,您可以轻松地实现事件触发和处理的机制。

  4. 多线程支持:在多线程编程中,委托可以用于实现异步操作和回调。您可以将方法传递给线程,让线程在适当的时候调用该方法,以便在后台执行任务并返回结果。

  5. 可读性和可维护性:使用委托可以使代码更具可读性和可维护性。通过使用委托,您可以明确地指定关注点和功能,并将其封装在独立的方法中。这样,代码变得更易于理解、调试和修改。

总的来说,委托提供了一种灵活且强大的机制,可以改善代码结构和组织,并支持一些重要的编程概念,如解耦、事件驱动和多线程编程。它是一种在Unity中常用的工具,可以提高代码的可维护性和可扩展性。

二、举例说明

1. 例1

举个例子来使用委托:我们先定义一个宠物名称委托,在TestA类中实现狗和猫的方法

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public delegate void PetName(string name); //委托 (需要一个string类型的参数当宠物名称)//陆地动物类
public class TestA : MonoBehaviour
{PetName petName; //声明委托void Start(){//委托petName += Dog; //狗petName += Cat; //猫//调用委托事件petName("大白");}//狗 因为委托调用所以需要一个string参数void Dog(string name){Debug.Log($"我叫{name},是一只狗");}//猫void Cat(string name){Debug.Log($"我叫{name},是一只猫");}
}

运行结果:
在这里插入图片描述

从中我们可以看到,当我们把两个方法(狗,猫)“添加”到委托中时,我们只需要调用定义的委托(petName方法) 就可以同时执行添加的两个方法。根据上面的委托的含义来解释,我们创建了一个petName委托当作容器,然后将dog(狗),cat(猫)方法添加到容器中,这样我们只需要执行容器就可以将容器中的所有方法都给执行。

2. 例2

委托创建时会定义方法的类型。(是否有无参数、有无返回值)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public delegate void DelegateA();               //无参无返回值
public delegate void DelegateB(string name);    //有参无返回值
public delegate string DelegateC();             //无参有返回值
public delegate string DelegateD(string name);  //有参有返回值//陆地动物类
public class TestA : MonoBehaviour
{//委托定义DelegateA delegateA;        //无参无返回值DelegateB delegateB;        //有参无返回值DelegateC delegateC;        //无参有返回值        DelegateD delegateD;        //有参有返回值void Start(){//添加方法delegateA = A;delegateB = B;delegateC = C;delegateD = D;//这里错误示范  delegateA委托添加B方法会报错,原因委托定义了方法类型,B方法类型不符合delegateA定义的方法类型会报错//delegateA += B;//运行delegateA();delegateB("");delegateC();delegateD("");}void A() {Debug.Log("无参无返回值");}void B(string name){Debug.Log("有参无返回值");}string C(){Debug.Log("无参有返回值");return "";}string D(string name){Debug.Log("有参有返回值");return "";}
}

运行结果:
在这里插入图片描述
错误示范:
在这里插入图片描述
delegateA委托添加B方法会报错,原因委托定义了方法类型,B方法类型不符合delegateAi定义的方法类型会报错

三、案例

举一个大家经常用的例子,你在CSDN中订阅一个博主的专栏(游戏专栏),当这个博主发布了这个专栏的一个最新文章,就会收到消息。这个就是用的委托,实现如下

1.创建一个博主类Blogger,负责书写文章,并且调用委托事件向订阅专栏的用于发送最新文章

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//这是一个博主类负责书写文章,并且调用委托事件向订阅专栏的用于发送最新文章
public class Blogger : MonoBehaviour
{public InputField articleName; //文章名称public Button uploadBtn; //上传文章void Start(){//按钮监听uploadBtn.onClick.AddListener(UpLoad);}//上传事件void UpLoad() {//上传文章名称不为空时if (articleName.text!=string.Empty){Debug.Log($"博主上传文章:{articleName.text}");}}
}

2.创建一个有参无返回值的订阅委托,用于存放订阅人员推送信息方法,并在博主类中声明创建。与上方博主类结合,完整代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public delegate void Subscribe(string name);//订阅委托 用于存放订阅人员的推送方法//这是一个博主类负责书写文章,并且调用委托事件向订阅专栏的用于发送最新文章
public class Blogger : MonoBehaviour
{public InputField articleName; //文章名称public Button uploadBtn; //上传文章public static Subscribe subscribe; //创建公用的静态订阅委托void Start(){//按钮监听uploadBtn.onClick.AddListener(UpLoad);}//上传事件void UpLoad() {//上传文章名称不为空时if (articleName.text!=string.Empty){Debug.Log($"博主上传文章:{articleName.text}");subscribe(articleName.text); //向订阅的人员发送信息}}
}

3.新建两个PeopleA、PeopleB人员类,在里面声明Push推送消息方法,并且在strat里添加到订阅委托中
PeopleA:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;//订阅人员A
public class PeopleA : MonoBehaviour
{void Start(){Blogger.subscribe += Push; //向订阅委托中添加人员A的推送方法}//推送信息void Push(string name){Debug.Log($"我是人员A,接收到博主最新文章:{name}");}
}

PeopleB:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;//订阅人员B
public class PeopleB : MonoBehaviour
{void Start(){Blogger.subscribe += Push; //向订阅委托中添加人员A的推送方法}//推送信息void Push(string name) {Debug.Log($"我是人员B,接收到博主最新文章:{name}");}
}

运行结果:
在这里插入图片描述

四、泛型委托Action和Func

在Unity中,我们除了可以自定义委托类型来定义委托,我们还可以使用C#类库,为我们已经准备好的两个内置委托类型(ActionFunc)来定义委托,它可以帮我们省去声明委托的这个步骤。它们都是泛型的委托,Action是一个不返回任何值的委托类型,而Func是一个具有返回值的委托类型。

要想使用【Action委托】或者【Func委托】,首先我们需要入System名称空间才能使用

1. Action委托

Action委托表示一个不返回值的方法,并且可以接受从0到16个参数。通过使用Action委托,可以定义并传递不同参数类型的方法。例如:

using UnityEngine;
using System;public class Example : MonoBehaviour
{// 定义一个Action委托,它没有返回值private Action<int> myAction;private void Start(){myAction += PrintNumber1;myAction += PrintNumber2;myAction(5);}private void PrintNumber1(int number){Debug.Log(number);}private void PrintNumber2(int number){Debug.Log(number+1);}
}

2. Func委托

Func委托表示一个具有返回值的方法,并且可以接受从0到16个参数。与Action委托不同,Func委托要求指定最后一个泛型参数作为返回类型。以下是一个示例:

using UnityEngine;
using System;public class Example : MonoBehaviour
{// 定义一个Func委托,它接受一个int类型的参数并返回一个字符串private Func<int, string> myFunc;private void Start(){myFunc = AddOneToString;string result = myFunc(10);Debug.Log(result); // 输出 "11"}private string AddOneToString(int number){return (number + 1).ToString();}
}

五、参考

  • 【文章】https://blog.csdn.net/qq_42345116/article/details/123408419
  • 【视频】https://www.bilibili.com/video/BV1U64y1F7c9

六、完结

如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦

好了,我是向宇,https://xiangyu.blog.csdn.net/

一位在小公司默默奋斗的开发者,出于兴趣爱好,于是最近才开始自习unity。如果你有任何问题,欢迎你来评论私信告诉我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

相关文章:

【unity小技巧】委托(Delegate)的基础使用和介绍

文章目录 一、前言1. 什么是委托&#xff1f;2. 使用委托的优点 二、举例说明1. 例12. 例2 三、案例四、泛型委托Action和Func1. Action委托2. Func委托 五、参考六、完结 一、前言 1. 什么是委托&#xff1f; 在Unity中&#xff0c;委托&#xff08;Delegate&#xff09;是一…...

【MySQL必知必会】第24章 使用游标(学习笔记)

游标 游标(cursor)是一个存储在MySQL服务器上的数据库查询&#xff0c;它不是一条select语句&#xff0c;而是被该语句检索出来的结果集游标主要用于交互式应用&#xff0c;其中用户需要滚动屏幕上的数据&#xff0c;并对数据进行浏览或做出更改只能用于存储过程&#xff0c;不…...

rosbag回放指定话题外的其他话题的方法

假设要回放file.bag包中除/tf话题外的所有话题 方法一 将原本/tf话题转发到另一个“黑洞话题”去&#xff0c;这样/tf话题就没输出了 rosbag play file.bag /tf:/tf_dev_null方法二 使用filter选项&#xff0c;重新生产一个新的不含/tf话题的包 rosbag filter file.bag fi…...

6.2.1 网络基本服务---域名解析系统DNS

6.2.1 网络基本服务—域名解析系统DNS 因特网是需要提供一些最基本的服务的&#xff0c;今天我们就来讨论一下这些基本的服务。 域名系统&#xff08;DNS&#xff09;远程登录&#xff08;Telnet&#xff09;文件传输协议&#xff08;FTP&#xff09;动态主机配置协议&#x…...

通用文字识别OCR 之实现自动化办公

摘要 随着技术的发展&#xff0c;通用文字识别&#xff08;OCR&#xff09;已经成为现代办公环境中不可或缺的工具之一。OCR技术可以将印刷或手写文本转换为可编辑或可搜索的数字文本&#xff0c;极大地提高了办公效率并实现了自动化办公。本文将深入探讨OCR技术在实现自动化办…...

Spring Boot 有哪些特点?

目录 一、自动配置 二、嵌入式 Tomcat Web 服务器 三、入门 POM 四、Actuator执行器 API 五、SpringBoot初始化器 一、自动配置 Spring Boot的自动配置是Spring Boot框架提供的一种功能&#xff0c;它可以根据用程序的依赖和配置信息&#xff0c;自动配置一些常见的功能模…...

10个图像处理的Python库

在这篇文章中&#xff0c;我们将整理计算机视觉项目中常用的Python库&#xff0c;如果你想进入计算机视觉领域&#xff0c;可以先了解下本文介绍的库&#xff0c;这会对你的工作很有帮助。 1、PIL/Pillow Pillow是一个通用且用户友好的Python库&#xff0c;提供了丰富的函数集…...

项目里不引入外网链接的解决方法

在写轮播的时候&#xff0c;引入了这个外网的资源是不对的 解决方法&#xff1a; 去外网上把文件下载下来&#xff0c;放在src文件夹下即可 在下面路径下引入下载的文件即可...

Java的jdk配置成功,但是输入java -version等,命令行没有任何反应

问题&#xff1a;现在有很多学生出现这种情况&#xff0c; Java的jdk配置成功&#xff0c;但是输入java -version等&#xff0c;命令行没有任何反应 Java下载后&#xff0c;手动配置环境变量&#xff0c;并且配置好&#xff0c;但是在命令行中无论输入java的什么都没有反应 问…...

MySQL select查询练习

一、创表并插入数据 创表&#xff1a; CREATE TABLE worker (部门号 int NOT NULL,职工号 int NOT NULL,工作时间 date NOT NULL,工资 float(8,2) NOT NULL,政治面貌 varchar(10) NOT NULL DEFAULT 群众,姓名 varchar(20) NOT NULL,出生日期 date NOT NULL,性别 char(1) DEFAU…...

Github 标星 60K,不愧是阿里巴巴内部出厂的“Java 核心面试神技”

前言 作为一个 Java 程序员&#xff0c;你平时总是陷在业务开发里&#xff0c;每天噼里啪啦忙敲着代码&#xff0c;上到系统开发&#xff0c;下到 Bug 修改&#xff0c;你感觉自己无所不能。然而偶尔的一次聚会&#xff0c;你听说和自己一起出道的同学早已经年薪 50 万&#x…...

git 使用教程

git 使用手册 参考链接&#xff1a; https://blog.csdn.net/wanjun_007/article/details/126770712 git给远程仓库添加分支并上传文件 注意&#xff1a;git init 是建一个自己的本地仓 0 &#xff1a; 先git clone master 分支 1. 先pull master分支 2. git checkout -b &q…...

【Vue2.0源码学习】模板编译篇-模板解析阶段(HTML解析器)

文章目录 1. 前言2. HTML解析器内部运行流程3. 如何解析不同的内容3.1 解析HTML注释3.2 解析条件注释3.3 解析DOCTYPE3.4 解析开始标签3.5 解析结束标签3.6 解析文本 4. 如何保证AST节点层级关系5. 回归源码5.1 HTML解析器源码5.2 parseEndTag函数源码 6. 总结 1. 前言 上篇文…...

ARM裸机开发-串口通信

一、在使用EXYNOS4412的串口发送和接收的时候&#xff0c;首先要对EXYNOS4412的串口进行配置&#xff0c;我们使用轮询方式时的配置有哪些&#xff1f; 1、配置GPIO&#xff0c;使对应管脚作为串口的发送和接收管脚 GPA0CON寄存器[7:4][3:0] 0x22 GPA0PUD寄存器[3:0] 0 禁止上…...

Dubbo分布式服务框架,springboot+dubbo+zookeeper

一Dubbo的简易介绍 1.Dubbo是什么&#xff1f; Dubbo是一个分布式服务框架&#xff0c;致力于提供高性能和透明化的RPC远程服务调用方案&#xff0c;以及SOA服务治理方案。 简单的说&#xff0c;dubbo就是个服务框架&#xff0c;如果没有分布式的需求&#xff0c;其实是不需…...

网络:UDP out of order;SIP;CPU out-of-order 执行

文章目录 问题SIP如果使用UDP出现乱序网络CPU问题 最近遇到虚拟机收到的UDP包发生乱序。从协议上说,这个乱序是标准,及特性所允许的,期望的。所以上层应用需要适应这种乱序,如果不能适应,可能需要做协议转换,专用TCP,让TCP来处理这种乱序的可能。 产生乱序的原因: 是网…...

我心中的TOP1编程语言—JavaScript

作为一名研发工程师&#xff08;程序员&#xff09;&#xff0c;平时工作中肯定会接触或了解很多编程语言。每个人都会有自己工作中常用的语言&#xff0c;也会有偏爱的一些编程语言。而我心中的最爱&#xff0c;毫无疑问&#xff0c;就是 JavaScript。 JavaScript 是一门编程…...

CentOS环境下的Maven安装

CentOS 安装 Maven 镜像地址 镜像地址&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/apache/maven/ 下载地址&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.8.8/binaries/ 下载maven 将下载好的压缩包拷贝到根目录下 解压 tar -zxvf ap…...

表的增删改查

1、创建表 mysql> create table employee ( -> id int(1) comment 员工编号, -> name varchar(6) comment 员工名字, -> gender varchar(2) comment 员工性别, -> salary int (4) comment 员工薪资); Query OK, 0 rows affected (0.01 sec) 2、…...

Tauri 应用中发送 http 请求

最近基于 Tauri 和 React 开发一个用于 http/https 接口测试的工具 Get Tools&#xff0c;其中使用了 tauri 提供的 fetch API&#xff0c;在开发调试过程中遇到了一些权限和参数问题&#xff0c;在此记录下来。 权限配置 在 tauri 应用中&#xff0c;如果想要使用 http 或 fe…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...