《UE5_C++多人TPS完整教程》学习笔记12 ——《P13 加入游戏会话(Joining The Sessions)》


本文为B站系列教学视频 《UE5_C++多人TPS完整教程》 —— 《P13 加入游戏会话(Joining The Session)》 的学习笔记,该系列教学视频为 Udemy 课程 《Unreal Engine 5 C++ Multiplayer Shooter》 的中文字幕翻译版,UP主(也是译者)为 游戏引擎能吃么。


文章目录

  • P13 加入游戏会话
  • 13.1 创建关卡
  • 13.2 设置及检查匹配类型
  • 13.3 获取游戏会话创建源地址
  • 13.4 进行测试
  • 13.5 Summary


P13 加入游戏会话

本节课将在《P11 设置加入游戏会话(Setup for Joining Sessions)》 代码的基础上,创建一个新关卡 “Lobby”,以便玩家在加入已创建的会话后可以前往该关卡等待其他玩家加入;我们还将在会话设置中指定匹配类型(Match type),确保为游戏会话设置正确的匹配类型;当游戏会话被查找到时,首先检查匹配类型,然后自动获取游戏会话创建源 IP 地址,以便我们加入游戏会话后可以前往关卡 “Lobby”。
在这里插入图片描述


13.1 创建关卡

  1. 新建 Basic 类型关卡,命名为 “Lobby”,保存到 “Content\ThirdPerson\Maps” 目录下。
    在这里插入图片描述
  2. 修改 “MenuSystemcharacter.cpp” 中回调函数 “OnCreateSessionComplete()”:如果游戏会话创建成功,进入关卡 “Lobby”。
    void AMenuSystemCharacter::OnCreateSessionComplete(FName SessionName, bool bWasSuccessful)
    {if (bWasSuccessful) {	// 如果游戏会话创建成功if (GEngine) {GEngine->AddOnScreenDebugMessage(	// 添加调试信息到屏幕上-1,								// 使用 -1 不会覆盖前面的调试信息15.f,							// 调试信息的显示时间FColor::Red,					// 字体颜色FString::Printf(TEXT("Create session: %s!"), *SessionName.ToString())	// 打印游戏会话的名称);}/* P13 加入游戏会话(Joining The Sessions)*/UWorld* World = GetWorld();if (World) {// Uworld->ServerTravel:https://docs.unrealengine.com/5.0/en-US/API/Runtime/Engine/Engine/UWorld/ServerTravel/World->ServerTravel(FString("/Game/ThirdPerson/Maps/Lobby?listen"));	// 作为监听服务器打开 Lobby 关卡}/* P13 加入游戏会话(Joining The Sessions)*/}else {	// 如果游戏会话创建失败...}
    }
    

13.2 设置及检查匹配类型

  1. 在函数 CreateGameSession() 的会话设置部分添加类型匹配设置。

    void AMenuSystemCharacter::CreateGameSession()	// 当按下数字键 1 时调用
    {...// 会话设置成员变量参阅及含义:https://docs.unrealengine.com/5.3/en-US/API/Plugins/OnlineSubsystem/FOnlineSessionSettings/SessionSettings->bIsLANMatch = false;			// 会话设置:不创建 LAN 连接SessionSettings->NumPublicConnections = 4;		// 会话设置:设置最大公共连接数为 4SessionSettings->bAllowJoinInProgress = true;	// 会话设置:在会话运行时允许其他玩家加入SessionSettings->bAllowJoinViaPresence = true;	// 会话设置:Steam 使用 Presence 搜索会话所在地区,确保连接正常工作SessionSettings->bShouldAdvertise = true;		// 会话设置:允许 Steam 发布会话SessionSettings->bUsesPresence = true;			// 会话设置:允许显示用户 Presence 信息SessionSettings->bUseLobbiesIfAvailable = true;	// (视频中未提及)会话设置:优先选择 Lobby API(Steam 支持 Lobby API)/* P13 加入游戏会话(Joining The Sessions)*/// void FOnlineSessionSettings::Set(FName Key, const FString& Value, EOnlineDataAdvertisementType::Type InType);SessionSettings->Set(FName("MatchType"), FString("FreeForAll"), EOnlineDataAdvertisementType::ViaOnlineServiceAndPing);/* P13 加入游戏会话(Joining The Sessions)*/...
    }
    
  2. 在回调函数 “OnFindSessionsComplete()” 中加入对游戏会话搜索结果进行匹配类型检查的代码。

    void AMenuSystemCharacter::OnFindSessionsComplete(bool bWasSuccessful)
    {for (auto Result : SessionSearch->SearchResults) {	// 遍历游戏会话搜索结果FString Id = Result.GetSessionIdStr();FString User = Result.Session.OwningUserName;/* P13 加入游戏会话(Joining The Sessions)*/FString MatchType;	// 保存游戏会话匹配类型Result.Session.SessionSettings.Get(FName("MatchType"), MatchType);	// 获取游戏会话匹配类型保存在 MatchType 中/* P13 加入游戏会话(Joining The Sessions)*/if (GEngine) {GEngine->AddOnScreenDebugMessage(	// 添加调试信息到屏幕上-1,								// 使用 -1 不会覆盖前面的调试信息15.f,							// 调试信息的显示时间FColor::Cyan,					// 字体颜色:蓝绿色FString::Printf(TEXT("Id: %s, User: %s!"), *Id, *User)	// 打印消息);}/* P13 加入游戏会话(Joining The Sessions)*/if (MatchType == FString("FreeForAll")) {if (GEngine) {GEngine->AddOnScreenDebugMessage(	// 添加调试信息到屏幕上-1,								// 使用 -1 不会覆盖前面的调试信息15.f,							// 调试信息的显示时间FColor::Cyan,					// 字体颜色:蓝绿色FString::Printf(TEXT("Joining Match Type: %s!"), *MatchType)	// 打印游戏会话匹配类型);}}/* P13 加入游戏会话(Joining The Sessions)*/}
    }
    

13.3 获取游戏会话创建源地址

  1. 添加代码到 “MenuSystemcharacter.h” 的类 “AMenuSystemCharacter” 中,定义委托 JoinSessionsCompleteDelegate、以及委托的回调函数 OnJoinSessionComplete()

    ...UCLASS(config=Game)
    class AMenuSystemCharacter : public ACharacter
    {GENERATED_BODY()...public:// 会话接口智能指针// IOnlineSessionPtr OnlineSessionInterface;	// 添加头文件 "Interfaces/OnlineSessionInterface.h" 后使用,更具可读性TSharedPtr<class IOnlineSession, ESPMode::ThreadSafe> OnlineSessionInterface;	// 使用 TSharedPtr 智能指针包装器进行声明protected:UFUNCTION(BlueprintCallable)void CreateGameSession();	// 创建游戏会话UFUNCTION(BlueprintCallable)void JoinGameSession();		// 加入游戏会话void OnCreateSessionComplete(FName SessionName, bool bWasSuccessful);	// 委托 CreateSessionCompleteDelegate 的回调函数void OnFindSessionsComplete(bool bWasSuccessful);	// 委托 FindSessionCompleteDelegate 的回调函数/* P13 加入游戏会话(Joining The Sessions)*/void OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result);	// 委托 JoinSessionCompleteDelegate 的回调函数/* P13 加入游戏会话(Joining The Sessions)*/private:// 类 FOnCreateSessionCompleteDelegate 在 UE 5.0 和 5.1 版本的头文件 "Interfaces/OnlineSessionInterface.h" 中声明// 而 5.2 和 5.3 版本的头文件 "Interfaces/OnlineSessionDelegates.h" 中声明FOnCreateSessionCompleteDelegate CreateSessionCompleteDelegate;	// 会话创建完成委托FOnFindSessionsCompleteDelegate FindSessionsCompleteDelegate;	// 会话查找完成委托TSharedPtr<FOnlineSessionSearch> SessionSearch;					// 会话查找智能指针/* P13 加入游戏会话(Joining The Sessions)*/FOnJoinSessionCompleteDelegate JoinSessionCompleteDelegate;		// 会话加入完成委托/* P13 加入游戏会话(Joining The Sessions)*/
    };
    
  2. 在 “MenuSystemcharacter.cpp” 构造函数 “AMenuSystemCharacter::AMenuSystemCharacter()” 中为委托 “JoinSessionCompleteDelegate” 绑定回调函数 “OnJoinSessionComplete()” ,并在回调函数 “OnFindSessionsComplete()” 中添加 “JoinSessionCompleteDelegate” 到委托列表。

    ...AMenuSystemCharacter::AMenuSystemCharacter() :	// 为委托绑定回调函数CreateSessionCompleteDelegate(FOnCreateSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnCreateSessionComplete)),FindSessionsCompleteDelegate(FOnFindSessionsCompleteDelegate::CreateUObject(this, &ThisClass::OnFindSessionsComplete)),/* P13 加入游戏会话(Joining The Sessions)*/ JoinSessionCompleteDelegate(FOnJoinSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnJoinSessionComplete))/* P13 加入游戏会话(Joining The Sessions)*/	
    {...}void AMenuSystemCharacter::OnFindSessionsComplete(bool bWasSuccessful)
    {/* P13 加入游戏会话(Joining The Sessions)*/if (!OnlineSessionInterface.IsValid()) {return;}/* P13 加入游戏会话(Joining The Sessions)*/for (auto Result : SessionSearch->SearchResults) {	// 遍历游戏会话搜索结果FString Id = Result.GetSessionIdStr();FString User = Result.Session.OwningUserName;/* P13 加入游戏会话(Joining The Sessions)*/FString MatchType;	// 保存游戏会话匹配类型Result.Session.SessionSettings.Get(FName("MatchType"), MatchType);	// 获取游戏会话匹配类型保存在 MatchType 中/* P13 加入游戏会话(Joining The Sessions)*/if (GEngine) {GEngine->AddOnScreenDebugMessage(	// 添加调试信息到屏幕上-1,								// 使用 -1 不会覆盖前面的调试信息15.f,							// 调试信息的显示时间FColor::Cyan,					// 字体颜色:蓝绿色FString::Printf(TEXT("Id: %s, User: %s!"), *Id, *User)	// 打印游戏会话匹配类型);}/* P13 加入游戏会话(Joining The Sessions)*/if (MatchType == FString("FreeForAll")) {if (GEngine) {GEngine->AddOnScreenDebugMessage(	// 添加调试信息到屏幕上-1,								// 使用 -1 不会覆盖前面的调试信息15.f,							// 调试信息的显示时间FColor::Cyan,					// 字体颜色:蓝绿色FString::Printf(TEXT("Joining Match Type: %s!"), *MatchType)	// 打印消息);}OnlineSessionInterface->AddOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegate);	// 添加委托到会话接口的委托列表const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();	//获取本地玩家指针// 第一个输入参数类型为 const FUniqueNetId &SearchingPlayerId// 第二个输入参数类型为 Fname SessionName// 第三个输入参数类型为 const FOnlineSessionSearchResult &DesiredSession,这里写 Result 即可OnlineSessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, Result);	// 调用在线接口函数加入会话}	/* P13 加入游戏会话(Joining The Sessions)*/}
    }...
    
  3. . 在回调函数 “OnJoinSessionComplete()” 中获取游戏会话创建源 IP 地址并打印在屏幕上,然后前往关卡 “Lobby”。保存代码并进行编译。

    void AMenuSystemCharacter::OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
    {/* P13 加入游戏会话(Joining The Sessions)*/if (!OnlineSessionInterface.IsValid()) {return;}FString Address;	// 保存游戏会话创建源地址if (OnlineSessionInterface->GetResolvedConnectString(NAME_GameSession, Address)) {if (GEngine) {GEngine->AddOnScreenDebugMessage(	// 添加调试信息到屏幕上-1,								// 使用 -1 不会覆盖前面的调试信息15.f,							// 调试信息的显示时间FColor::Yellow,					// 字体颜色:黄色FString::Printf(TEXT("Connect string: %s!"), *Address)	// 打印游戏会话创建源 IP 地址);}}APlayerController* PlayerController = GetGameInstance()->GetFirstLocalPlayerController();	// 获取玩家控制器if (PlayerController) {PlayerController->ClientTravel(Address, ETravelType::TRAVEL_Absolute);	// 客户端传送至关卡 “Lobby”}/* P13 加入游戏会话(Joining The Sessions)*/
    }
    

13.4 进行测试

  1. 将项目打包之后发送到另一台设备上。在设备 1 上运行游戏(保证 Steam 已经运行),按下数字键 “1”,屏幕左上角红色字体显示会话的名称 “Game Session” ,并且当前关卡跳转至 “Lobby”,说明设备 1 创建会话成功。
    在这里插入图片描述

  2. 在设备 2 上运行游戏(保证 Steam 已经运行且登录的账户与设备1 上登录的账号不同),按下数字键 “2”,屏幕左上角蓝绿色字体显示设备 1 上登录到 Steam 的 ID 和用户名以及设备 1 创建的游戏会话匹配类型 “FreeForAll”,黄色字体显示设备 1 的 IP 地址,当前关卡跳转至 “Lobby”,并且可以看到有两个玩家存在,说明设备 2 找到并加入了设备 1 创建的会话中。
    在这里插入图片描述


13.5 Summary

本节课创建了一个 Basic 类型的新关卡 “Lobby”,使得玩家在加入已创建的会话后可以前往该关卡等待其他玩家的加入。接着,在会话设置 “SessionSettings” 中添加了匹配类型指定和检查的代码,确保为游戏会话设置正确的匹配类型。然后,定义委托 “JoinSessionCompleteDelegate” ,为它绑定回调函数 “OnJoinSessionComplete()”,在回调函数 “OnFindSessionsComplete()” 中添加 “JoinSessionCompleteDelegate” 到在线接口委托列表,通过在线接口函数 “GetResolvedConnectString()” 获取游戏会话创建源 IP 地址,使用函数 “ClientTravel()”进行客户端传送至关卡 “Lobby”。最后在两台设备上登录两个不同的 Steam 账号,以进行创建会话和加入会话测试。
在这里插入图片描述


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

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

相关文章

手把手教你开发Python桌面应用-PyQt6图书管理系统-修改密码UI设计实现

锋哥原创的PyQt6图书管理系统视频教程&#xff1a; PyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~_哔哩哔哩_bilibiliPyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~共计24条视频&…

Linux第46步_通过“添加自定义菜单”来学习menuconfig图形化配置原理

通过“添加自定义菜单”来学习menuconfig图形化配置原理&#xff0c;将来移植linux要用到。 自定义菜单要求如下: ①、在主界面中添加一个名为“My test menu”&#xff0c;此菜单内部有一个配置项。 ②、配置项为“MY TESTCONFIG”&#xff0c;此配置项处于菜单“My test m…

Spring Security实现权限认证与授权

一、Spring Security Spring Security作为Spring家族的安全框架&#xff0c;在安全方面的两个核心功能是认证&#xff08;Authentication&#xff09;和授权&#xff08;Authorization&#xff09;。 &#xff08;1&#xff09;用户认证指的是&#xff1a;验证某个用户是否为系…

【Java程序设计】【C00265】基于Springboot的地方废物回收机制管理系统(有论文)

基于Springboot的地方废物回收机制管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的地方废物回收机构管理系统 本系统分为管理员功能模块以及员工功能模块。 管理员功能模块&#xff1a;管理员登录系统后…

EXCEL中如何调出“数据分析”的菜单

今天发现&#xff0c;原来WPS还是和EXCEL比&#xff0c;还是少了“数据分析”这个日常基本做统计的菜单&#xff0c;只好用EXCEL了&#xff0c;但奇怪发现我的EXCEL中没发现这个菜单&#xff0c;然后查了下&#xff0c;才发现&#xff0c;要用如下的方法打开&#xff1a; 1&…

Go+:一种简单而强大的编程语言

Go是一种简单而强大的编程语言&#xff0c;它是在Go语言之上构建的&#xff0c;旨在提供更加强大、灵活和易于使用的编程体验。Go与Go语言共享大部分语法和语义&#xff0c;因此Go开发人员可以很快上手Go&#xff0c;同时也可以使用Go来编写更加简洁和高效的代码。在本文中&…

STM32自学☞定时器定时中断案例

timer_interrupt.c文件 /* 初始化函数编写步骤&#xff1a; 1.打开时钟 2.选择时基单元的时钟源&#xff08;内部时钟源&#xff09; 3.配置时基单元 4.NVIC配置 5.启动定时器 */ #include "stm32f10x.h" #include "stm32f10x_tim.h" #include …

CVE-2022-25578 漏洞复现

CVE-2022-25578 路由/admin/admin.php是后台&#xff0c;登录账号和密码默认是admin、tao&#xff0c;选择文件管理。 是否还记得文件上传中的.htaccess配置文件绕过发&#xff0c;在这个文件中加入一句AddType application/x-httpd-php .jpg&#xff0c;将所有jpg文件当作php…

位运算+leetcode(1)

基础 1.基础知识 以下都是针对数字的二进制进行操作 >> 右移操作符<< 左移操作符~ 取反操作符 & 有0就是0&#xff0c;全一才一 | 有一才一 &#xff0c;全0才0^ 相同为0&#xff0c;相异为1 异或( ^ )运算的规律 a ^ 0 a a ^ a 0a ^ b ^ c a ^ (b …

MyBatis篇----第一篇

系列文章目录 文章目录 系列文章目录前言一、什么是 Mybatis?二、Mybaits 的优点三、MyBatis 框架的缺点前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 一、什么…

【记录】电容的作用,调试Arduino及ESP8266

最近调试Arduino结合ESP8266进行WIFI传输和云端控制&#xff0c;准备用Arduino的3.3V输出直接作为ESP8266的电源&#xff0c;不想竟掉坑里了。 Arduino的3.3V输出接上ESP8266后&#xff0c;Arduino的程序就跑飞了。ESP8266刚上电还是相当生猛的&#xff0c;要吃掉一百多毫安的…

每日一练:LeeCode-617、合并二叉树【二叉树+DFS】

本文是力扣LeeCode-617、合并二叉树【二叉树DFS】 学习与理解过程&#xff0c;本文仅做学习之用&#xff0c;对本题感兴趣的小伙伴可以出门左拐LeeCode。 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&#xff0c;两…

Z-Stack一直卡在HAL_BOARD_INIT();

原因是Debugger没有配置好&#xff0c;因为默认是Simulator&#xff0c;不是TI的驱动&#xff0c;所以仿真出现一直卡在 HAL_BOARD_INIT(); 的情况&#xff0c;解决方法就是将Simulator改为Texas Instruments 改成下面的样子

static

静态方法中,没有this关键字 静态方法中,只能访问静态 非静态方法可以访问所有 隐含了一个this

CSP-动态规划-最长公共子序列(LCS)

一、动态规划 动态规划&#xff08;Dynamic Programming&#xff0c;简称DP&#xff09;主要用于求解可以被分解为相似子问题的复杂问题&#xff0c;特别是在优化问题上表现出色&#xff0c;如最短路径、最大子数组和、编辑距离等。动态规划的核心思想是将原问题分解为较小的子…

STM32 USART串口通信

目录 USART串口 串口发送 串口发送接收 串口收发HEX数据包 串口收发文本数据包 USART串口 串口发送 Serial.c #include "stm32f10x.h" // Device header #include "stdio.h" #include "stdarg.h"/*** brief 初始化串口以…

HTML 超文本标记语言

超文本标记语言 HTML 在一个客户程序主窗口上显示出的万维网文档称为页面 (page)。 页面制作的标准语言&#xff1a;HTML。 超文本标记语言 HTML (HyperText Markup Language) 是一种制作万维网页面的标准语言&#xff0c;它消除了不同计算机之间信息交流的障碍&#xff0c…

SQLyog安装配置(注册码)连接MySQL

下载资源 博主给你打包好了安装包&#xff0c;在网盘里&#xff0c;只有几Mb&#xff0c;防止你下载到钓鱼软件 快说谢谢博主&#xff08;然后心甘情愿的点个赞~&#x1f60a;&#xff09; SQLyog.zip 安装流程 ①下载好压缩包后并解压 ②打开文件夹&#xff0c;双击安装包 ③…

GPT 3.5 真的比 4.0聪明吗?

GPT 3.5 真的比 4.0聪明吗&#xff1f; DeepGo 计算机杂谈及深度学习记录&分享 在大语言模型大杀四方的今天 无论是哪个行业的工作人员 都用上了各种各样的模型 其中的佼佼者就是 ChatGPT! 众所周知 ChatGPT是有氪金的Plus4.0版本 那3.5真的不如4.0吗&#xff1f; 今天 我们…

【51单片机】DS18B20(江科大)

一、DS18B20温度传感器 1.DS18B20介绍 DS18B20是一种常见的数字温度传感器,其控制命令和数据都是以数字信号的方式输入输出,相比较于模拟温度传感器,具有功能强大、硬件简单、易扩展、抗干扰性强等特点 测温范围 :- 55℃到125℃ 通信接口:1-Wire(单总线) 其它特征:可形成…