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

news2024/9/25 19:25:24

文章目录

  • 一、前言
    • 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.coloradmin.cn/o/738582.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2FRE-10B-35-G24电比例调速阀控制器

2FRE-06B-20-G24、2FRE-10B-35-G24、2FRE-10B-50-G24、2FRE-16B-80-G24、2FRE-16B-115-G24、2FRE-16B-160-G24电比例调速阀&#xff0c;通过给定电信号&#xff0c;控制阀出口流量大小&#xff0c;并且采用压力补偿原理&#xff0c;保证输出流量大小不受负载压力影响维持恒定;该…

低代码平台实用吗?有哪些大型企业在用低代码?

一、目前正在使用低代码平台的企业有哪些&#xff1f; &#xff08;例举一些各行业规模较大的企业&#xff09; 制造行业&#xff1a;施耐德电气、吉利汽车、科大能通、伟星集团、远东控股、一汽大众、老板电器、双菱电梯、君乐宝。 建筑行业&#xff1a;中国交建、筑福集团…

【C++STL】“vector“用法 入门必备 超详细

vector用法 什么是vector&#xff1f;vector的使用vector的定义(构造函数)vector iterator 的使用迭代器演示范围for vector 空间增长扩容机制 vector 的增删查改assignvector 迭代器失效问题。 &#x1f340;小结&#x1f340; &#x1f389;博客主页&#xff1a;小智_x0___0x…

关于将Leetcode上代码直接复制到自己环境中的问题

实例代码&#xff08;不考虑代码的优劣性&#xff09;&#xff1a; 注&#xff1a;我用的是一个在线平台的编译器 Problem1 NameError&#xff1a;name ‘List’ is not defined 解决方法&#xff1a;添加下面代码&#xff1a; from typing import ListProblem2 TypeError…

Android Glide预加载preload ,kotlin

Android Glide预加载preload ,kotlin val imageView findViewById<ImageView>(R.id.image_view)Glide.with(this).asBitmap().load(image_file.path).signature(ObjectKey(image_file.path)).addListener(object : RequestListener<Bitmap> {override fun onLoadF…

抓取唯美图库(BeautifulSoup)

使用BeautifulSoup 1、拿到主页面的源代码&#xff0c;然后提取到子页面的简介地址&#xff0c;href 2、通过href拿到子页面的内容。从子页面中找到导图片的下载地址 img -> src 3、下载图片 import requests from bs4 import BeautifulSoupurlhttps://www.umei.cc/bizhi…

qt 闹钟实现

实现一个闹钟 自定义时间 按下开始后 开始计时&#xff0c;结束计时会播报语音 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimer> #include <QTimerEvent> #include <QDateTime> #include <QTime> #include …

【Leetcode】37.解数独(困难)

一、题目 1、题目描述 编写一个程序,通过填充空格来解决数独问题。 数独的解法需 遵循如下规则: 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图) 数独部分空格内已填入了数字…

UVM中测试用例的启动

一、命令行指定 ./simv -l simv.log UVM_TESTNAMEmy_case0 其中 UVM_TESTNAMEmy_case0 中的my_case0就是测试用例的名字 二、文件结构 在test文件夹中my_case0.sv对应case的名字 三、文件说明 3.1 my_case0.sv 其中其他都是写死的&#xff0c;只有红框的部分根据具体的代码…

温度反转效应Temperature Inversion(载流子迁移率与过阈值电压 谁占主导)

In general, as temperature increases, the delay of standard cells increases because of mobility degradation at higher temperatures.    But in lower technology nodes the impact of temperature on the delay of the cell is inverse. In lower nodes, the delay …

上海亚商投顾:沪指维持震荡 光伏等新能源赛道走强

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪 大小指数今日集体反弹&#xff0c;沪指高开后维持震荡走势&#xff0c;创业板指盘中涨超2%&#xff0c;午后涨幅有…

ts开发npm依赖包(插件)demo

序&#xff1a;涉及如下几个点 1、用js开发依赖包&#xff08;换个说法&#xff1a;你在开发第三方的\node_modules的插件了&#xff09; 2、用ts开发依赖包 3、解决本地开发的npm包重命名后不生效的问题 一、js版&#xff08;简单的&#xff09; 你直接在你的项目的\node_mod…

ndp48-web.exe_ndp48-x86-x64-allos-enu.exe_ndp48-x86-x64-allos-chs.exe下载地址

ndp48-web.exe、ndp48-x86-x64-allos-enu.exe、ndp48-x86-x64-allos-chs.exe下载地址 我发现网上几乎找不到地方直接下载&#xff0c;费了我九牛二虎的搜商&#xff0c;才发现原来可以这么下载。 我们可以去微软官方地址下载&#xff1a;下载 .NET Framework 4.8

react 利用antd-mobile实现楼层效果

首先是js模块 import React, { useEffect, useRef, useState } from react import { SideBar } from antd-mobile import ./louceng.css import { useThrottleFn } from ahooksconst items [{ key: 1, title: 第一项, text: <div>12313212313第一项12313212313第一项1…

图床项目之公网发布和测试

项目发布和测试 一、http服务测试1.1、ab http压力测试1.2、post测试&#xff08;注册请求和登录请求&#xff09; 二、性能测试2.1、生成测试脚本2.2、上传测试2.2.1、单客户端测试本地上传到本机服务器2.2.2、如果使用集群的方式进行测试 2.3、下载测试2.4、删除测试2.5、测试…

Vivado2018.3安装教程

1 下载安装包 这个软件是免费的&#xff0c;去官网注册即可完成下载。 https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/archive.html 2 解压安装包 注意&#xff1a;安装包需要解压到一个全英文路径 3 安装 1.双…

linux与windows趣味谈

文章目录 前言linux&windows两者常见的系统版本系统安装版本选择linux和windows使用体验聊聊折腾收获Linux系统使用技巧 前言 windows和linux同为常见的操作系统&#xff0c;相信大部分人对widows比较熟悉一点&#xff0c;对linux比较陌生一点儿。但相信&#xff0c;作为程…

如何利用MES管理系统做到车间可视化管理

车间可视化管理是提高生产效率和质量的关键一环。而MES生产管理系统能够为企业提供车间实时数据监控、生产计划管理、异常处理等功能&#xff0c;帮助企业实现车间可视化管理。本文将介绍如何利用MES生产管理系统做到车间可视化管理&#xff0c;包括数据采集、数据分析、实时监…

Error:java: 不再支持源选项 5 请使用 6 或更高版本。

今天电脑重新安装系统&#xff0c;安装jdk环境选择了11版本&#xff0c;但是创建工程时突然报错 报错&#xff1a;Error:java: 不再支持源选项 5 请使用 6 或更高版本 解决方案&#xff1a; 1.查看project setting中的project 和Modules的版本号是否与本机jdk的版本号是否一…

基于单片机快递柜的设计与实现

功能介绍 以51单片机作为主控系统&#xff1b;液晶显示当前信息&#xff0c;最多可存储几十个&#xff1b;按下存储按键液晶显示当前快递柜剩余数量&#xff1b;继电器打开&#xff0c;表示用来放物品&#xff1b;正次按下存储按键将取消存快递&#xff0c;继电器关闭快递柜可用…