本文为B站系列教学视频 《UE5_C++多人TPS完整教程》 —— 《P9 访问 Steam(Acessing Steam)》 的学习笔记,该系列教学视频为 Udemy 课程 《Unreal Engine 5 C++ Multiplayer Shooter》 的中文字幕翻译版,UP主(也是译者)为 游戏引擎能吃么。
文章目录
- P9 访问 Steam
- 9.1 访问在线子系统
- 9.2 打印在线子系统的名称
- 9.3 Summary
P9 访问 Steam
本节课将接着上节课 《P8 为项目配置 Steam(Configuring A Project for Steam)》 的内容,在项目配置好 Steam
平台在线子系统后,尝试访问 Steam
在线子系统,通过打印子系统到屏幕上以查看我们连接到哪个子系统上,同时也可以验证我们的配置是否成功。
9.1 访问在线子系统
-
打开 Visual Studio,在右侧解决方案资源管理器展开 “
/Games/MenuSystem/Source/MenuSystem/
”,打开 “MenuSystemcharacter.h
”,添加头文件 “OnlineSubsystem.h
”,继续添加代码到类 “AMenuSystemCharacter
” 中:... UCLASS(config=Game) class AMenuSystemCharacter : public ACharacter { GENERATED_BODY() ... public: /* P9 访问 Steam(Acessing Steam)*/ // 会话接口智能指针 IOnlineSessionPtr OnlineSessionInterface; /* P9 访问 Steam(Acessing Steam)*/ }; ...
注意:
- 如果打开 Visual Studio 后在右侧解决方案资源管理器看到
MenuSystem (未找到)
,则需要在虚幻引擎中 “刷新 Visual Studio 项目”,然后重新打开。
- 如下图,添加的头文件代码
#include "OnlineSubsystem.h"
必须放在#include "MenuSystemCharacter.generated.h"
前面。
如果放在后面会报错。
- 如果打开 Visual Studio 后在右侧解决方案资源管理器看到
-
打开 “
MenuSystemcharacter.cpp
” ,添加代码到类 “AMenuSystemCharacter
” 的构造函数 “AMenuSystemCharacter::AMenuSystemCharacter()
” 中:AMenuSystemCharacter::AMenuSystemCharacter() { IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get(); // 获取当前的在线子系统指针 if (OnlineSubsystem) { // 如果当前在线子系统有效 OnlineSessionInterface = OnlineSubsystem->GetSessionInterface(); // 获取会话接口智能指针 } }
-
尝试进行编译,编译失败,Visual Studio 错误提示消息中包括 “E0349 没有与这些握作数匹配的“=" 运算符” 以及 “C2679 二元"=": 没有找到接受”InlineSessionPtr"类型的右择作数的运算符(没有可接受的转换)。
而视频中出现的错误如下:
使用实时编译出现错误 “UnrealEditor - MenuSystem.dll is not currently enabled for Live Coding”,解决方法参阅《UE5 C++报错:is not currently enabled for Live Coding》,或者也可以先使用离线编译。实时编译和离线编译的区别参阅 《UE5_C++多人TPS完整教程》学习笔记4 ——《P5 局域网连接(LAN Connection)》
如果按照 《UE5 C++报错:is not currently enabled for Live Coding》 重新生成项目文件后,出现错误提示 “MenuSystem could not be compiled. Try rebuilding from source manually.”,即虚幻引擎不能自动编译、打开编辑器窗口,则使用 Visual Studio 中打开 “MenuSystem.sln
”,在菜单栏中选择 “生成解决方案(B)” 进行离线编译,但需要先确保代码没有报错(也就是先按步骤 4 中修改好代码)。
-
这里提供两种解决方法:
① 直接添加头文件 “Interfaces/OnlineSessionInterface.h
” 即可,头文件中包含了 “IOnlineSessionPtr
” 的声明。
② 由于 “IOnlineSessionPtr
” 使用了 “typedef
” 关键字,它是一个指向 “IOnlineSession
” 的共享指针类型 “TsharedPtr
” 多线程安全版本的别名,因此在没有添加头文件 “Interfaces/OnlineSessionInterface.h
” 的情况下需要按照 “TSharedPtr
” 智能指针包装器(Smart pointer wrapper)声明变量:将代码改为 “TSharedPtr<class IOnlineSession, ESPMode::ThreadSafe> OnlineSessionInterface;
” 即可。共享指针类型 “TsharedPtr
” 的学习可以参阅虚幻引擎官方文档《虚幻智能指针库》、《共享指针》。
视频采用了第 ② 种解决方法。
使用智能指针的优点:
- 防止内存泄漏:共享引用不存在时,智能指针(弱指针除外)会自动删除对象。
- 弱引用:弱指针会中断引用循环并阻止悬挂指针。
- 可选择的线程安全:虚幻智能指针库包括线程安全代码,可跨线程管理引用计数。如无需线程安全,可用其换取更好性能。
- 运行时安全:共享引用从不为空,可固定随时取消引用。
- 授予意图:可轻松区分对象所有者和观察者。
- 内存:智能指针在64位下仅为C++指针大小的两倍(加上共享的16字节引用控制器)。唯一指针除外,其与C++指针大小相同。
线程安全:通常仅在单线程上访问智能指针的操作才是安全的。如需访问多线程,请使用智能指针类的线程安全版本:- TSharedPtr<T, ESPMode::ThreadSafe>
- TSharedRef<T, ESPMode::ThreadSafe>
- TWeakPtr<T, ESPMode::ThreadSafe>
- TSharedFromThis<T, ESPMode::ThreadSafe>
—— 虚幻引擎官方文档《虚幻智能指针库》
- 重新进行编译,编译成功。
9.2 打印在线子系统的名称
-
继续在 “
MenuSystemcharacter.cpp
” 构造函数 “AMenuSystemCharacter::AMenuSystemCharacter()
” 中添加打印子系统名称到屏幕上的代码。AMenuSystemCharacter::AMenuSystemCharacter() { IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get(); // 获取当前的在线子系统指针 if (OnlineSubsystem) { // 如果当前在线子系统有效 OnlineSessionInterface = OnlineSubsystem->GetSessionInterface(); // 获取会话接口智能指针 if (GEngine) { GEngine->AddOnScreenDebugMessage( // 添加调试信息到屏幕上 -1, // 使用 -1 不会覆盖前面的调试信息 15.f, // 调试信息的显示时间 FColor::Blue, // 字体颜色 FString::Printf(TEXT("Found subsystem %s!"), *OnlineSubsystem->GetSubsystemName().ToString()) // 打印在线子系统的名称 ); } } }
调用全局变量
GEngine
指针调用函数AddOnScreenDebugMessage
节点,进行屏幕输出。void AddOnScreenDebugMessage { int32 Key, float TimeToDisplay, FColor Di splayColor, const FString & DebugMessage, bool bNewerOnTop, const FVector2D & TextScale }
Key = -1
时,则添加新的消息,不会覆盖旧有消息(当Key = -1
时,bNewerOnTop
有效,直接添加到队列最上层)Key != -1
时,则更新现有消息,效率更高。
—— 《虚幻引擎基础入门(C++) — 【日志输出篇 03】》
-
进行实时编译,编译成功。
如果采用离线编译出现视频中的如下错误,先关闭 Visual Studio,删除项目目录下
Binaries
文件夹,鼠标右键单击 “MenuSystem.uproject
”,在下拉菜单栏中选择 “Generate Visual Studio project files”,然后左键单击 “MenuSystem.uproject
”重构项目。
-
下载并安装
Steam
平台客户端(官方下载地址:https://store.steampowered.com/),然后注册账户进行登录。此过程可能需要科学上网,也可以下载Watt Tookit
(官方下载地址:https://steampp.net/) 加速。
-
在编辑器中播放游戏,无论切换到哪个网络模式,屏幕上显示的在线子系统名称都是 “NULL”。
-
将项目打包之后再运行游戏(保证
Steam
已经运行),可以看到屏幕上显示的在线子系统名称为Steam
,并且Steam
在右下角弹出通知。
9.3 Summary
本节课通过编写 C++ 代码尝试访问 Steam
在线子系统,通过打印子系统名称到屏幕上验证访问是否成功。
在 9.1 访问在线子系统 的 步骤 1 中使用函数 AddOnScreenDebugMessage()
进行屏幕消息输出时,若函数第一个入参 “int32 Key
” 为 -1 ,则添加新的消息,不会覆盖旧有消息(当 Key
为 -1 时,bNewerOnTop
有效,直接添加到队列最上层),若 Key
不为 -1 ,则更新现有消息。
在 步骤 3 中如果使用实时编译出现错误 “UnrealEditor - MenuSystem.dll is not currently enabled for Live Coding”,解决方法参阅《UE5 C++报错:is not currently enabled for Live Coding》,或者也可以先使用离线编译。如果按照这篇博文重新生成项目文件后,出现错误提示 “MenuSystem could not be compiled. Try rebuilding from source manually.”,使用 Visual Studio 中进行离线编译,但需要先按照 步骤 4 修改代码,保证代码没有报错。
本小节最关键的步骤在于声明 “IOnlineSessionPtr
” 变量需要按照 “TSharedPtr
” 智能指针包装器(Smart pointer wrapper)声明变量。共享指针类型 “TsharedPtr
” 的学习可以参阅虚幻引擎官方文档《虚幻智能指针库》、《共享指针》。
在 9.2 打印在线子系统的名称 的 步骤 2 中,进行编译时出现视频中的错误 “无法删除热重载文件…”,只需要删除项目目录下 Binaries
文件夹,重新生成项目文件、重构项目即可。
在 步骤 4 和 步骤 5 中,可以看到在 PIE 模式下无论切换任何网络模式打印出的在线子系统名称都是 “NULL
”;而将项目打包以后再次运行游戏,可以成功打印出在线子系统名称为 “Steam
”。