本文为B站系列教学视频 《UE5_C++多人TPS完整教程》 —— 《P21 更多的子系统委托(More Subsystem Delegates)》 的学习笔记,该系列教学视频为计算机工程师、程序员、游戏开发者、作家(Engineer, Programmer, Game Developer, Author) Stephen Ulibarri 发布在 Udemy 上的课程 《Unreal Engine 5 C++ Multiplayer Shooter》 的中文字幕翻译版,UP主(也是译者)为 游戏引擎能吃么。
P21 更多的子系统委托
本节课将创建更多的子系统委托,包括搜索、加入、销毁和开始会话委托,然后创建与它们分别绑定的回调函数。
21.1 创建更多的委托以及回调函数
-
在 “
MultiplayerSessionsSubsystem.h
” 中分别使用创建静态和动态多播委托的宏来声明更多的与搜索会话、加入会话、销毁会话、开始会话相关的自定义子系统委托类型,然后再使用这些定义委托变量。
静态和动态多播委托的区别在于动态多播委托允许在蓝图中使用,而静态多播委托不可以。在创建搜索会话完成和加入会话完成这两个委托类型时,由于它们的入参 “FOnlineSessionSearchResult
” 和 “EOnJoinSessionCompleteResult
” 并非UCLASS
或USTRUCT
类型,不能在蓝图中实现回调,因此这里使用静态多播委托来声明搜索会话完成和加入会话完成两个委托。... // 使用创建动态多播委托的宏来声明将与菜单类上的回调函数绑定的自定义委托 DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSubsystemOnCreateSessionCompleteDelegate, bool, bWasSuccessful); /* P21 更多的子系统委托(More Subsystem Delegates)*/ DECLARE_MULTICAST_DELEGATE_TwoParams(FSubsystemOnFindSessionsCompleteDelegate, const TArray<FOnlineSessionSearchResult>& SearchResults, bool bWasSuccessful); // FOnlineSessionSearchResult 不是 UCLASS 或 USTRUCT,不能在蓝图中实现回调,因此这里使用静态多播委托 // 如果想要实现整个菜单类和蓝图,并从蓝图中进行回调,需要使用事件调度器, // 创建一个 UCLASS 或 USTRUCT,其中包含有关搜索结果的代码,然后使用动态多播委托传递信息 // 但我们正在使用 C++ 而非蓝图实现菜单类,为了让工作不会过于复杂,我们只使用静态多播委托而非动态。 DECLARE_MULTICAST_DELEGATE_OneParam(FSubsystemOnJoinSessionCompleteDelegate, EOnJoinSessionCompleteResult::Type Result); // EOnJoinSessionCompleteResult 也是不是 UCLASS 或 USTRUCT,不能在蓝图中实现回调,因此这里也要使用静态多播委托 DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSubsystemOnDestroySessionCompleteDelegate, bool, bWasSuccessful); DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSubsystemOnStartSessionCompleteDelegate, bool, bWasSuccessful); /* P21 更多的子系统委托(More Subsystem Delegates)*/ /** /** * */ UCLASS() class MULTIPLAYERSESSIONS_API UMultiplayerSessionsSubsystem : public UGameInstanceSubsystem { GENERATED_BODY() public: ... // 将与菜单类上的回调函数绑定的自定义委托 FSubsystemOnCreateSessionCompleteDelegate SubsystemOnCreateSessionCompleteDelegate; /* P21 更多的子系统委托(More Subsystem Delegates)*/ FSubsystemOnFindSessionsCompleteDelegate SubsystemOnFindSessionsCompleteDelegate; FSubsystemOnJoinSessionCompleteDelegate SubsystemOnJoinSessionCompleteDelegate; FSubsystemOnDestroySessionCompleteDelegate SubsystemOnDestroySessionCompleteDelegate; FSubsystemOnStartSessionCompleteDelegate SubsystemOnStartSessionCompleteDelegate; /* P21 更多的子系统委托(More Subsystem Delegates)*/ ... };
-
在 “
Menu.h
” 中加入头文件 “Interfaces/OnlineSessionInterface.h
” 和 “OnlineSessionSettings.h
”,创建与上述自定义子系统委托类型相关的回调函数,其中销毁会话和开始会话委托的回调函数声明需要使用UFUNCTION()
宏。... #include "Interfaces/OnlineSessionInterface.h" #include "OnlineSessionSettings.h" ... UCLASS() class MULTIPLAYERSESSIONS_API UMultiplayerSessionsSubsystem : public UGameInstanceSubsystem { GENERATED_BODY() ... protected: UFUNCTION() // 虚幻引擎的反射机制可以仅根据函数名来正确绑定回调函数,如果绑定失败说明没有找到函数,需要使用 UFUNCTION() 宏。 void OnCreateSession(bool bWasSuccessful); /* P21 更多的子系统委托(More Subsystem Delegates)*/ void OnFindSessions(const TArray<FOnlineSessionSearchResult>& SearchResults, bool bWasSuccessful); void OnJoinSession(EOnJoinSessionCompleteResult::Type Result); UFUNCTION() void OnDestroySession(bool bWasSuccessful); UFUNCTION() void OnStartSession(bool bWasSuccessful); /* P21 更多的子系统委托(More Subsystem Delegates)*/ ... };
-
在 “
Menu.cpp
” 的 “MenuSetup
” 函数中实现委托与回调函数的绑定,其中查找和加入会话委托的回调函数的绑定需要用到委托的 “AddUObject()
” 方法,销毁和开始会话委托的回调函数的绑定需要用的委托的 “AddDynamic()
” 方法。void UMenu::MenuSetup(int32 NumberOfPublicConnections, FString TypeOfMatch) { ... // 绑定菜单类回调函数到子系统委托上 if (MultiplayerSessionsSubsystem) { MultiplayerSessionsSubsystem->SubsystemOnCreateSessionCompleteDelegate.AddDynamic(this, &ThisClass::OnCreateSession); /* P21 更多的子系统委托(More Subsystem Delegates)*/ MultiplayerSessionsSubsystem->SubsystemOnFindSessionsCompleteDelegate.AddUObject(this, &ThisClass::OnFindSessions); MultiplayerSessionsSubsystem->SubsystemOnJoinSessionCompleteDelegate.AddUObject(this, &ThisClass::OnJoinSession); MultiplayerSessionsSubsystem->SubsystemOnDestroySessionCompleteDelegate.AddDynamic(this, &ThisClass::OnDestroySession); MultiplayerSessionsSubsystem->SubsystemOnStartSessionCompleteDelegate.AddDynamic(this, &ThisClass::OnStartSession); /* P21 更多的子系统委托(More Subsystem Delegates)*/ } }
21.2 Summary
本节课分别使用创建静态的宏来声明搜索会话、加入会话的自定义子系统委托,使用动态多播委托的宏来声明销毁会话、开始会话的委托,然后分别创建与它们绑定的回调函数,其中查找和加入会话委托的回调函数的绑定需要用到委托的 “AddUObject()
” 方法,销毁和开始会话委托的回调函数的绑定需要用的委托的 “AddDynamic()
” 方法。
在 21.1 创建自定义委托及与其绑定的回调函数 的 步骤 1 创建搜索会话完成和加入会话完成这两个委托类型时,由于它们的入参 “FOnlineSessionSearchResult
” 和 “EOnJoinSessionCompleteResult
” 并非 UCLASS
或 USTRUCT
类型,不能在蓝图中实现回调,因此这里使用静态多播委托来声明搜索会话完成和加入会话完成两个委托。
在 步骤 2 中,头文件 “Interfaces/OnlineSessionInterface.h
” 和 “OnlineSessionSettings.h
” 加入 “Menu.h
” 可以防止 “EOnJoinSessionCompleteResult::Type
” 未识别而报错。