学习虚幻C++开发日志——委托(持续更新中)

委托

官方文档:Delegates and Lamba Functions in Unreal Engine | 虚幻引擎 5.5 文档 | Epic Developer Community | Epic Developer Community

简单地说,委托就像是一个“函数指针”,但它更加安全和灵活。它允许程序在运行时动态地调用不同的函数。

(1)解耦对象间的关联

委托允许对象之间以松散耦合的方式进行通信。通过委托,一个对象可以在不直接引用另一个对象的情况下,通知其执行特定的操作。这有助于降低对象之间的依赖性和耦合度,从而提高代码的灵活性和可维护性。

(2)事件驱动编程

委托是实现事件驱动编程的关键机制之一。在事件驱动编程中,对象的行为是基于事件的发生来触发的。委托允许对象在事件发生时通知其他对象,并允许这些对象对事件做出响应。这种机制使得代码更加模块化,并易于扩展和维护。

(3)泛型且类型安全

委托提供了一种泛型但类型安全的方式,在C++对象上调用成员函数。通过委托,你可以动态地绑定到任意对象的成员函数,即使调用程序不知道对象的具体类型也可以进行操作。这增加了代码的灵活性和可重用性,同时保证了类型安全。

(4)异步通信

委托还支持异步通信。在虚幻引擎中,许多操作可能需要花费一些时间才能完成,如加载资源、执行物理模拟等。通过使用委托,你可以在不阻塞主线程的情况下,通知其他对象在异步操作完成后执行特定的操作。这有助于提高应用程序的响应性和性能。

(5)广播和多播

虚幻引擎中的委托还支持广播和多播机制。广播允许一个委托通知所有绑定的对象,而多播则允许一个委托通知多个指定的对象。这种机制使得在多个对象之间传递消息变得更加简单和高效。

(6)蓝图可视化编程支持

在虚幻引擎的蓝图可视化编程环境中,委托也扮演着重要的角色。通过委托,蓝图脚本可以轻松地与C++代码进行交互,从而实现更加复杂和灵活的游戏逻辑。此外,蓝图还支持动态多播委托的声明和使用,这使得在蓝图中处理事件和消息变得更加方便。

(7)复制和安全性

委托对象在复制时是很安全的。你可以通过值或引用来传递委托,但需要注意的是,通过值传递需要在堆上分配内存,这通常不是最佳实践。通过引用传递则更加高效且安全。

但传递引用,在异步的情况下会涉及到生命周期问题,容易崩溃,虚幻的委托大部分时候拷贝是安全的,因为它会存一个执行委托对象的弱引用,如果这对象消亡了,那么这个委托被调用的时候就不会执行。

委托的大致使用流程

  • 声明委托类型
  • 定义委托类型变量
  • 通过委托变量绑定委托函数
  • 执行委托
  • 解绑委托函数(可根据自身情况而实施)

1.单播

先创建一个继承于Actor的类,并在其头文件包含头文件(此处文件命名为LearnSingleDelegateActor)

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "LearnSingleDelegateActor.generated.h"

 并在源文件添加GameplayStatics.h头文件

#include"Kismet/GameplayStatics.h"

(1)声明委托类型 

DECLARE_DELEGATE(FLearnSingleDelegatePrintLocation);
DECLARE_DELEGATE_RetVal_OneParam(FVector,FLearnSingleDelegateGetLocation,FString);
//DECLARE_DELEGATE_RetVal_OneParam(ReturnType, DelegateName, ParamType);
//ReturnType:委托将要返回的值的类型。
//DelegateName:委托的名称,这个名称将用于在代码中引用这个委托类型。
//ParamType:委托将要接受的参数的类型。

如需声明委托,请使用下文所述的宏。请根据与委托相绑定的函数(或多个函数)的函数签名来选择宏。每个宏都为新的委托类型名称、函数返回类型(如果不是 void 函数)及其参数提供了参数。当前,支持以下使用任意组合的委托签名:

  • 返回一个值的函数。
  • 声明为常函数。
  • 最多4个"载荷"变量。
  • 最多8个函数参数。

注意:委托函数支持与UFunctions相同的说明符,但使用 UDELEGATE 宏而不是 UFUNCTION

(2)定义委托类型变量

在ALearnSingleDelegateActor类内定义变量

public:FLearnSingleDelegatePrintLocation SingleDelegatePrintLocation;FLearnSingleDelegateGetLocation SingleDelegateGetLocation;

(3)通过委托变量绑定委托函数

为方便在ALearnSingleDelegateActor类头文件再创建一个类,此处命名为LearnLocationActor(继承于Actor)

UCLASS()
class ALearnLocationActor : public AActor
{GENERATED_BODY()public:ALearnLocationActor();protected:virtual void BeginPlay() override;void PrintLocation();FVector GetLocation(FString InStr);//此处类型看委托声明处,与其相对应.
};

在此默认函数中创建根组件来便于观察委托操作 ,并对其他函数进行定义

ALearnLocationActor::ALearnLocationActor()
{RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("LocationRoot"));
}void ALearnLocationActor::PrintLocation()
{FVector MyLocation = GetActorLocation();UE_LOG(LogTemp, Warning, TEXT("[%s]__PrintMyLocation:[%s]"), *FString(__FUNCTION__), *MyLocation.ToString());//用于被绑定时观察步骤实现
}FVector ALearnLocationActor::GetLocation(FString InStr)
{FVector MyLocation = GetActorLocation();UE_LOG(LogTemp, Warning, TEXT("[%s]__GetMyLocation:[%s]"), *FString(__FUNCTION__), *MyLocation.ToString());return MyLocation;
}

 此处绑定函数

void ALearnLocationActor::BeginPlay()
{AActor *ActorPtr = UGameplayStatics::GetActorOfClass(this, ALearnSingleDelegateActor::StaticClass());if (ALearnSingleDelegateActor* SingleDelegateActorPtr=Cast<ALearnSingleDelegateActor>(ActorPtr)){//通过SingleDelegatePrintLocation此委托变量使用BindUObject函数模板绑定委托并调用一次绑定函数SingleDelegateActorPtr->SingleDelegatePrintLocation.BindUObject(this,&ALearnLocationActor::PrintLocation);SingleDelegateActorPtr->SingleDelegateGetLocation.BindUObject(this, &ALearnLocationActor::GetLocation);}
}

 官方模板函数

(4) 执行委托

为了观察实现步骤,我在LearnSingleDelegateActor类声明函数暴露给蓝图

	UFUNCTION(BlueprintCallable, Category = "Learn")void CallLocationActorPrint();UFUNCTION(BlueprintCallable, Category = "Learn")void CallLocationActorGet();

并对其进行定义

void ALearnSingleDelegateActor::CallLocationActorPrint()
{//第一种写法if (SingleDelegatePrintLocation.IsBound()){SingleDelegatePrintLocation.Execute();//SingleDelegatePrintLocation.Unbind();解绑操作}//第二种写法(建议用此写法)SingleDelegatePrintLocation.ExecuteIfBound();
}void ALearnSingleDelegateActor::CallLocationActorGet()
{FVector MyRecetivedLocation = SingleDelegateGetLocation.Execute(TEXT("My Single Delegate Actor"));UE_LOG(LogTemp, Warning, TEXT("[MyRecetivedLocation]__MyLocation:[%s]"), *MyRecetivedLocation.ToString());
}

 注意:对于无返回值的委托,可调用ExecuteIfBound()函数,但需注意输出参数可能未初始化。

(5)观察实现步骤(只做演示)

1、将两个类拖入场景中

2、在关卡蓝图处使用函数(此处是使用键盘1、2分别去激活函数)

3、启动关卡,并在输出日志观察

2.多播

3.动态单播

4.动态多播

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

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

相关文章

Git入门图文教程 -- 深入浅出 ( 保姆级 )

01、认识一下Git&#xff01;—简介 Git是当前最先进、最主流的分布式版本控制系统&#xff0c;免费、开源&#xff01;核心能力就是版本控制。再具体一点&#xff0c;就是面向代码文件的版本控制&#xff0c;代码的任何修改历史都会被记录管理起来&#xff0c;意味着可以恢复…

多传感器融合slam过程解析【大白话版】

SLAM&#xff08;同步定位与地图构建&#xff09;是自动驾驶、机器人导航和三维建模的关键技术之一。多传感器融合&#xff08;激光雷达、IMU、相机&#xff09;进一步提升了SLAM的鲁棒性和适应性&#xff0c;使其能够在复杂环境中实时构建高精度地图。本文将围绕激光雷达IMU相…

蓝桥杯每日真题 - 第18天

题目&#xff1a;&#xff08;出差&#xff09; 题目描述&#xff08;13届 C&C B组E题&#xff09; 解题思路&#xff1a; 问题分析 问题实质是一个带权图的最短路径问题&#xff0c;但路径的权重包含两个部分&#xff1a; 从当前城市到下一个城市的路程时间。 当前城市的…

每日论文23-24ESSERC 6.4-16.1Ghz混合并联-串联谐振器

《A 6.4-to-16.1GHz Hybrid Parallel-Series Resonator Mode-Switching Oscillator with 206.6dBc/Hz FoMT at 1MHz Offset in 40nm CMOS》 24ESSERC 首先这篇文章有个地方我其实没太明白&#xff0c;它在title和行文的时候都写的是“ hybrid parallel-series resonator mode-…

<QNAP 453D QTS-5.x> 日志记录:在 Docker 中运行的 Flask 应用安装 自签名 SSL 证书 解决 Chrome 等浏览器证书安全

原因&#xff1a;Chrome 不信任 ssc 证书 使启用了 HTTPS&#xff0c;即使有使用 自签名证书 (self-signed certificate 非由可信的证书颁发机构 【CA&#xff0c;Certificate Authority】签发的&#xff09;。浏览器 Chrome 默认不信任自签名证书&#xff0c;也会报 NET::ERR_…

【再谈设计模式】适配器模式 ~接口兼容的桥梁

一、引言 在软件开发的复杂世界里&#xff0c;不同的组件、类或者系统往往有着各自独立的设计和接口定义。当需要将这些原本不兼容的部分整合在一起协同工作时&#xff0c;就像尝试将方形的榫头插入圆形的卯眼一样困难。适配器设计模式就如同一位神奇的工匠&#xff0c;能够巧妙…

无人机的激光雷达避障系统阐述!

一、材料 激光二极管基底材料&#xff1a;激光二极管是激光雷达的核心组件之一&#xff0c;其基底材料通常采用硅或砷化镓。硅材料成本低、易于加工&#xff0c;但发光效率相对较低&#xff1b;而砷化镓材料发光效率高&#xff0c;但成本较高。 光学镜片材料&#xff1a;激光…

一篇快速上手 Axios,一个基于 Promise 的网络请求库(涉及原理实现)

Axios 1. 介绍1.1 什么是 Axios&#xff1f;1.2 axios 和 ajax 的区别 2. 安装使用3. Axios 基本使用3.1 Axios 发送请求3.2 其他方式发送请求3.3 响应结构3.4 Request Config3.5 默认配置3.6 创建实例对象发送请求 3.7 拦截器3.8 取消请求 4. 模拟 Axios4.1 axios 对象创建过程…

Three.js 相机控制器Controls

在 3D 场景中&#xff0c;摄像机的控制尤为重要&#xff0c;因为它决定了用户如何观察和与场景互动。Three.js 提供了多种相机控制器&#xff0c;最常用的有 OrbitControls、TrackballControls、FlyControls 和 FirstPersonControls。OrbitControls 适合用于查看和检查 3D 模型…

【新人系列】Python 入门(十一):控制结构

✍ 个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4dd; 专栏地址&#xff1a;https://blog.csdn.net/newin2020/category_12801353.html &#x1f4e3; 专栏定位&#xff1a;为 0 基础刚入门 Python 的小伙伴提供详细的讲解&#xff0c;也欢迎大佬们…

SELinux

一、简介 SELinux : 安全强化的Linux&#xff1b;在开启后,会对进程本身部署安全上下文&#xff1b;会对文件部署安全上下文&#xff1b;对法务使用端口进行限制&#xff1b;对程序本身的不安全功能做限制 二、工作原理 1、工作方式 通过MAC的方式来控制管理进程&#xff0…

C++小白实习日记——Day 5 gitee怎么删文件,测试文件怎么写循环

昨晚一直内耗&#xff0c;一个程序写了三天写不出来&#xff0c;主要是耗时太多了&#xff0c;老板一直不满意。想在VScode上跑一下&#xff0c;昨晚一直报错。今天来公司重新搞了一下&#xff0c; 主要工作有&#xff1a; 1&#xff0c;读取当前时间用tscns 2&#xff0c;输…

Apache Paimon】-- 6 -- 清理过期数据

目录 1、简要介绍 2、操作方式和步骤 2.1、调整快照文件过期时间 2.2、设置分区过期时间 2.2.1、举例1 2.2.2、举例2 2.3、清理废弃文件 3、参考 1、简要介绍 清理 paimon &#xff08;表&#xff09;过期数据可以释放存储空间&#xff0c;优化资源利用并提升系统运行效…

阿里云IIS虚拟主机部署ssl证书

宝塔配置SSL证书用起来是很方便的&#xff0c;只需要在站点里就可以配置好&#xff0c;但是云虚拟主机在管理的时候是没有这个权限的&#xff0c;只提供了简单的域名管理等信息。 此处记录下阿里云&#xff08;原万网&#xff09;的IIS虚拟主机如何配置部署SSL证书。 进入虚拟…

BOM的详细讲解

BOM概述 BOM简介 BOM&#xff08;browser Object&#xff09;即浏览器对象模型&#xff0c;它提供了独立于内容而与浏览器窗口进行交互的对象&#xff0c;其核心对象是window。 BOM由一系列的对象构成&#xff0c;并且每个对象都提供了很多方法与属性 BOM缺乏标准&#xff…

湘潭大学软件工程算法设计与分析考试复习笔记(四)

回顾 湘潭大学软件工程算法设计与分析考试复习笔记&#xff08;一&#xff09;湘潭大学软件工程算法设计与分析考试复习笔记&#xff08;二&#xff09;湘潭大学软件工程算法设计与分析考试复习笔记&#xff08;三&#xff09; 前言 现在是晚上十一点&#xff0c;我平时是十…

STM32单片机ADC数模转换器

由于最近忘记了&#xff0c;自用。 转换模式 单次转换&#xff0c;非扫描模式 在非扫描模式下&#xff0c;列表中就只有序列1的位置有效&#xff0c;此时可以在序列1的位置指定我们想要转换的通道&#xff0c;然后ADC就会对这个通道进行模数转换。等待一段时间&#xff0c;转…

android 使用MediaPlayer实现音乐播放--获取音乐数据

前面已经添加了权限&#xff0c;有权限后可以去数据库读取音乐文件&#xff0c;一般可以获取全部音乐、专辑、歌手、流派等。 1. 获取全部音乐数据 class MusicHelper {companion object {SuppressLint("Range")fun getMusic(context: Context): MutableList<Mu…

Spring Boot中使用AOP和反射机制设计一个的幂等注解(两种持久化模式),简单易懂教程

该帖子介绍如何设计利用AOP设计幂等注解&#xff0c;且可设置两种持久化模式 1、普通模式&#xff1a;基于redis的幂等注解&#xff0c;持久化程度较低 2、增强模式&#xff1a;基于数据库&#xff08;MySQL&#xff09;的幂等注解&#xff0c;持久化程度高 如果只需要具有re…