目录
- [0 引言](#0 引言)
- [1 多人游戏会话](#1 多人游戏会话)
-
- [1.1 Why?为什么要有这个](#1.1 Why?为什么要有这个)
- [1.2 How?怎么使用?](#1.2 How?怎么使用?)
- [2 加入游戏会话的流程](#2 加入游戏会话的流程)
0 引言
理解服务器和客户端是如果加载到一个游戏会话,有助于网络开发。
1 多人游戏会话
1.1 Why?为什么要有这个
游戏会话(Session)的概念在多人游戏中起到了至关重要的作用。它不仅帮助玩家找到并加入游戏,还确保了游戏的状态同步、资源管理、安全性和稳定性等。通过会话管理系统,开发者可以更容易地实现复杂的多人游戏功能,提供更好的游戏体验。
1.2 How?怎么使用?
在开发多人网络游戏时,使用游戏会话(Session)是非常常见且必要的。游戏会话帮助管理玩家的连接、匹配、游戏状态同步等多个方面,使得多人游戏的开发和运行更加顺畅。以下是如何在开发过程中使用游戏会话的详细步骤和示例。
- 选择合适的在线子系统(Online Subsystem)
Unreal Engine(UE)提供了多种在线子系统(如Steam、Epic Online Services、Xbox Live等),你需要选择一个适合你的游戏需求的子系统。通常在项目设置中配置:
cpp
// 在DefaultEngine.ini中配置
[OnlineSubsystem]
DefaultPlatformService=Null // 或者是Steam, EOS等
- 创建游戏会话
创建会话是由服务器或主机发起的,通常包括设置会话参数(如最大玩家数量、游戏模式、地图等)。以下是一个简单的示例:
cpp
void AMyGameInstance::CreateGameSession()
{
IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get();
if (OnlineSubsystem)
{
IOnlineSessionPtr Sessions = OnlineSubsystem->GetSessionInterface();
if (Sessions.IsValid())
{
FOnlineSessionSettings SessionSettings;
SessionSettings.bIsLANMatch = true;
SessionSettings.NumPublicConnections = 4;
SessionSettings.bShouldAdvertise = true;
SessionSettings.bUsesPresence = true;
Sessions->CreateSession(0, NAME_GameSession, SessionSettings);
}
}
}
- 查找游戏会话
客户端需要查找可用的会话以便加入游戏。以下是查找会话的示例:
cpp
void AMyGameInstance::FindGameSessions()
{
IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get();
if (OnlineSubsystem)
{
IOnlineSessionPtr Sessions = OnlineSubsystem->GetSessionInterface();
if (Sessions.IsValid())
{
TSharedRef<FOnlineSessionSearch> SessionSearch = MakeShareable(new FOnlineSessionSearch());
SessionSearch->bIsLanQuery = true;
SessionSearch->MaxSearchResults = 10;
SessionSearch->PingBucketSize = 50;
Sessions->FindSessions(0, SessionSearch);
}
}
}
- 加入游戏会话
客户端选择一个会话并发送加入请求。以下是加入会话的示例:
cpp
void AMyGameInstance::JoinGameSession()
{
IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get();
if (OnlineSubsystem)
{
IOnlineSessionPtr Sessions = OnlineSubsystem->GetSessionInterface();
if (Sessions.IsValid())
{
FOnlineSessionSearchResult SearchResult;
// 假设已经找到一个有效的会话
Sessions->JoinSession(0, NAME_GameSession, SearchResult);
}
}
}
- 销毁游戏会话
当游戏结束或需要关闭会话时,服务器或主机可以销毁会话。以下是销毁会话的示例:
cpp
void AMyGameInstance::DestroyGameSession()
{
IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get();
if (OnlineSubsystem)
{
IOnlineSessionPtr Sessions = OnlineSubsystem->GetSessionInterface();
if (Sessions.IsValid())
{
Sessions->DestroySession(NAME_GameSession);
}
}
}
- 处理会话事件
在实际开发中,你还需要处理各种会话事件(如会话创建成功、查找会话完成、加入会话成功等)。这些事件通常通过委托(Delegate)来处理:
cpp
void AMyGameInstance::OnCreateSessionComplete(FName SessionName, bool bWasSuccessful)
{
// 处理会话创建完成的逻辑
}
void AMyGameInstance::OnFindSessionsComplete(bool bWasSuccessful)
{
// 处理查找会话完成的逻辑
}
void AMyGameInstance::OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
{
// 处理加入会话完成的逻辑
}
- 配置和调试
确保在项目设置中正确配置了在线子系统,并在开发过程中进行充分的测试和调试。你可以使用UE的日志系统来记录和调试会话管理的各个步骤。
总结:在开发多人网络游戏时,使用游戏会话是管理玩家连接、匹配、游戏状态同步等的重要手段。通过选择合适的在线子系统,创建、查找、加入和销毁会话,并处理相关事件,你可以实现一个功能完善的多人游戏系统。
2 加入游戏会话的流程
在专用服务器模式下,服务器和客户端的启动和连接过程,以及GameMode、PlayerController、Pawn的网络同步创建,是多人游戏开发中的关键部分。以下是详细的步骤和流程:
- 启动专用服务器
专用服务器通常在命令行或脚本中启动。以下是启动专用服务器的命令示例:
sh
UE4Editor.exe YourProjectName -server -log
或者通过打包后的可执行文件启动:
sh
YourProjectNameServer.exe YourMapName?listen -log
- 客户端加入游戏会话
客户端需要连接到专用服务器。你可以在游戏逻辑中实现连接功能,例如在主菜单中添加一个按钮来连接到服务器:
cpp
void UMyMainMenuWidget::OnJoinServerButtonClicked()
{
UMyGameInstance* GameInstance = Cast<UMyGameInstance>(GetGameInstance());
if (GameInstance)
{
GameInstance->FindGameSessions();
}
}
在找到会话后,客户端可以通过以下命令连接到服务器:
cpp
void UMyGameInstance::JoinGameSession()
{
if (SessionInterface.IsValid() && SessionSearch.IsValid())
{
for (const FOnlineSessionSearchResult& SearchResult : SessionSearch->SearchResults)
{
if (SearchResult.IsValid())
{
SessionInterface->JoinSession(0, NAME_GameSession, SearchResult);
break;
}
}
}
}
- GameMode、PlayerController、Pawn的网络同步创建
在专用服务器模式下,GameMode、PlayerController、Pawn的创建和同步是通过UE的网络框架自动处理的。以下是详细的流程:
GameMode
- 服务器端创建:当服务器启动并加载地图时,GameMode在服务器端创建。GameMode只存在于服务器端,不会在客户端创建。
- 管理游戏规则:GameMode负责管理游戏规则、玩家连接、关卡切换等。
PlayerController
- 客户端请求连接:当客户端请求连接到服务器时,服务器会为每个连接的客户端创建一个PlayerController。
- 服务器端创建 :服务器在接收到客户端的连接请求后,调用
APlayerController::ClientTravel
来通知客户端进行地图加载和PlayerController的创建。 - 客户端同步:客户端在接收到服务器的通知后,同步创建PlayerController。
Pawn
- 服务器端创建:当PlayerController在服务器端创建后,服务器会根据GameMode的设置为每个PlayerController生成一个Pawn。
- 客户端同步:服务器生成的Pawn会通过网络同步到客户端。客户端会创建一个与服务器端Pawn对应的代理(Replicated Proxy)。
- 控制权:PlayerController在客户端控制Pawn的移动和操作,服务器会同步这些操作给其他客户端。
总结
在专用服务器模式下,服务器和客户端的启动和连接过程,以及GameMode、PlayerController、Pawn的网络同步创建,是通过UE4的网络框架自动处理的。服务器负责创建和管理GameMode、PlayerController和Pawn,并通过属性复制和RPC机制将这些对象的状态和操作同步到客户端。客户端则根据服务器的指令同步创建和更新这些对象,从而实现一致的游戏体验。