【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。如果你有任何问题,欢迎你来评论私信告诉我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/18159.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【分布式】 ELK 企业级日志分析系统 二

目录 一、FilebeatELK 部署1.1 环境部署 二、grok 正则捕获插件mutate 数据修改插件multiline 多行合并插件date 时间处理插件 一、FilebeatELK 部署 1.1 环境部署 Node1节点&#xff08;2C/4G&#xff09;&#xff1a;node1/192.168.137.101 Elasticsearch Node2节点&…

【Distributed】分布式ELK日志文件分析系统(二)

文章目录 一、FilebeatELK 部署1. 环境部署2. 在 Filebeat 节点上操作2.1 安装 Filebeat2.2 设置 filebeat 的主配置文件 3. 在 Apache 节点上操作3.1 在 Logstash 组件所在节点上新建一个 Logstash 配置文件 3. 启动3.1 在Logstash 组件所在节点启动3.2 在 Filebeat 节点 启动…

git报错:remote: Access denied (URL 403)

git报错&#xff1a;remote: Access denied fatal: unable to access ‘ https:/ /gitee. cohe requested URL 403 大概的原因&#xff0c;是之前更改了 可能因为我之前在git bash中配过ssh&#xff0c;系统已经将指向git的用户设置了别的位置&#xff0c;所以…

基础篇--单片机简介

单片机简介 视频教程 单片机是什么 单片机&#xff1a;Single-Chip Microcomputer 单片微型计算机&#xff0c;是一种集成电路芯片 单片机有什么用&#xff1f; 单片机发展历程 单片机发展超势 CISC Vs RISC CISC和RISC举例 https://wenku.baidu.com/view/b074b0ed998fcc22b…

使用均值漂移来量化带宽分类数据

均值漂移概念 均值漂移的基本概念&#xff1a;沿着密度上升方向寻找聚簇点&#xff0c;其计算过程如下&#xff1a; 1 均值漂移算法首先找到一个中心点center&#xff08;随机选择&#xff09;&#xff0c;然后根据半径划分一个范围 把这个范围内的点输入簇x的标记个数加1 2 在…

【JavaEE】JVM的组成及类加载过程

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶 本文我们主要讲解一下面试中常见的问题&#xff0c;如果想深入了解&#xff0c;请看一下《Java虚拟机规范》这本书 目录 文章目录 一、JVM简介 二、JVM整体组成 2.1 运行时数据区组成 2.2…

ELK日志记录——Kibana组件——grok 正则捕获插件

grok 正则捕获插件 grok 使用文本片段切分的方式来切分日志事件 内置正则表达式调用 %{SYNTAX:SEMANTIC} ●SYNTAX代表匹配值的类型&#xff0c;例如&#xff0c;0.11可以NUMBER类型所匹配&#xff0c;10.222.22.25可以使用IP匹配。 ●SEMANTIC表示存储该值的一个变量声明&…

生产环境 kafka 平滑迁移之旅

文章目录 背景分析测试环境验证现实很残酷两种抉择-----leader分区切换方案选择实施步骤手工副本集增加步骤手工leader分区切换步骤 总结 背景 线上kafka集群&#xff0c;3台机器&#xff0c;3个broker&#xff1b;其中某台机器因为硬件故障&#xff0c;需要停机维修&#xff…

表的增删改查

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、…

解析三防平板在工业自动化的应用价值

三防平板作为一种具有出色性能和特殊设计的电子设备&#xff0c;为工业自动化领域带来了巨大的应用价值。采用英特尔凌动四核处理器&#xff0c;三防平板具备先进的技术与处理能力。同时配备Window 10操作系统&#xff0c;这款三防平板能够轻松执行多种任务指令。此外&#xff…

支持向量机推导之r||w||=1的限制转化

支持向量机推导之r||w||1的限制转化 很多同学肯定是学过支持向量机的&#xff0c;也可能大致的理解了支持向量机这个算法&#xff0c;我想大部分人在学习这个算法的时候&#xff0c;对于推导过程有一步应该是不太理解。 我先简要介绍一下SVM,SVM的核心思想在于找到一个多维空间…

基于深度学习的高精度深海鱼检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度深海鱼检测识别系统可用于检测与定位深海鱼目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的深海鱼目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型训练数据集&a…