《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.hqwc.cn/news/467215.html

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

相关文章

操作系统基础:IO管理概述【上】

&#x1f308;个人主页&#xff1a;godspeed_lucip &#x1f525; 系列专栏&#xff1a;OS从基础到进阶 &#x1f3c6;&#x1f3c6;本文完整PDF源文件请翻阅至文章底部下载。&#x1f3c6;&#x1f3c6; &#x1f3ae;1 I/O设备的基本概念与分类&#x1f52b;1.1 总览&#x…

最新Burp Suite入门讲解

Burp Suite的安装 Burp Suite是一款集成化的渗透测试工具&#xff0c;包含了很多功能&#xff0c;可以帮助我们高效地完成对Web应用程序的渗透测试和安全检测。 Burp Suite由Java语言编写&#xff0c;Java自身的跨平台性使我们能更方便地学习和使用这款软件。不像其他自动化测…

HTML 超文本标记语言

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

P1164 小A点菜题解

题目 uim拿到了uoi的镭牌后&#xff0c;立刻拉着基友小A到了一家餐馆&#xff0c;很低端的那种。uim指着墙上的价目表&#xff08;太低级了没有菜单&#xff09;&#xff0c;说&#xff1a;“随便点”。 不过uim由于买了一些书&#xff0c;口袋里只剩M元(M≤10000)。 餐馆虽…

【Java程序设计】【C00269】基于Springboot的漫画网站(有论文)

基于Springboot的漫画网站&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的漫画网站 本系统分为系统功能模块、管理员功能模块、以及用户功能模块。 系统功能模块&#xff1a;在系统首页可以查看首页、漫画投稿、…

Ubuntu20.04更新Cmake版本详解

最近在跑一个融合惯导定位的slam框架ins_eskf_kitti&#xff0c;在框架的安装过程中&#xff0c;需要对从GitHub上克隆下来的glog进行编译。其命令如下&#xff1a; glog&#xff1a; git clone https://github.com/google/glog.git cd glog mkdir build cd build cmake .. m…

【实战】一、Jest 前端自动化测试框架基础入门(中) —— 前端要学的测试课 从Jest入门到TDD BDD双实战(二)

文章目录 一、Jest 前端自动化测试框架基础入门5.Jest 中的匹配器toBe 匹配器toEqual匹配器toBeNull匹配器toBeUndefined匹配器和toBeDefined匹配器toBeTruthy匹配器toBeFalsy匹配器数字相关的匹配器字符串相关的匹配器数组相关的匹配器异常情况的匹配器 6.Jest 命令行工具的使…

Spring Boot 笔记 012 创建接口_添加文章分类

1.1.1 实体类添加校验 package com.geji.pojo;import jakarta.validation.constraints.NotEmpty; import lombok.Data;import java.time.LocalDateTime;Data public class Category {private Integer id;//主键IDNotEmptyprivate String categoryName;//分类名称NotEmptypriva…

Google刚刚推出了图神经网络Tensorflow-GNN

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

jsp课程教学管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 课程教学管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0…

Linux network namespace 访问外网以及多命名空间通信(经典容器组网 veth pair + bridge 模式认知)

写在前面 整理K8s网络相关笔记博文内容涉及 Linux network namespace 访问外网方案 Demo实际上也就是 经典容器组网 veth pair bridge 模式理解不足小伙伴帮忙指正 不必太纠结于当下&#xff0c;也不必太忧虑未来&#xff0c;当你经历过一些事情的时候&#xff0c;眼前的风景已…

java之Maven

1. maven Maven是管理和构建java项目的工具 项目依赖资源(jar包)的管理,避免版本冲突统一项目结构项目构建&#xff0c;标准跨平台(Linux,window,MacOS)的自动化项目管理 2.maven依赖仓库 2.maven安装 maven安装视频教程 3. IDEA集成Maven 4. maven的依赖范围 5. maven生命…