0、前言

最近项目需要实现多人联机功能,人数不固定,但肯定不少,因此希望借助UE的网络同步功能快速实现。
根据官方的专用服务器教程可知,向OpenLevel传输一个IP地址即可实现。经测试,该方法仅支持16人同步,肯定是不能满足需求的。

1、寻找客户端上限检测机制

在服务端的Log中可以看到,当底17个客户端开始尝试链接时,会弹出一个Server Full的错误,借此定位到

FString AGameSession::ApproveLogin(const FString& Options)
{
...
if (AtCapacity(SpectatorOnly == 1))
{
return TEXT( "Server full." );
}
...
}

再看AtCapacity

bool AGameSession::AtCapacity(bool bSpectator)
{
if ( GetNetMode() == NM_Standalone )
{
return false;
}
AGameModeBase* GameMode = GetWorld()->GetAuthGameMode();
if ( bSpectator )
{
return ( (GameMode->GetNumSpectators() >= MaxSpectators)
&& ((GetNetMode() != NM_ListenServer) || (GameMode->GetNumPlayers() > 0)) );
}
else
{
const int32 MaxPlayersToUse = CVarMaxPlayersOverride.GetValueOnGameThread() > 0 ? CVarMaxPlayersOverride.GetValueOnGameThread() : MaxPlayers;
return ( (MaxPlayersToUse>0) && (GameMode->GetNumPlayers() >= MaxPlayersToUse) );
}
}

这个参数是链接参数中仅观战的标志位,1为观战玩家,因此这里只关心最后一个return

const int32 MaxPlayersToUse = CVarMaxPlayersOverride.GetValueOnGameThread() > 0 ? CVarMaxPlayersOverride.GetValueOnGameThread() : MaxPlayers;

大概意思就是,检查是否有用命令修改过链接人数,有就用命令设置的,没有就读这个成员变量。

UCLASS(config=Game, notplaceable)
class ENGINE_API AGameSession : public AInfo
{
/** Maximum number of players allowed by this server. */
UPROPERTY(globalconfig)
int32 MaxPlayers;
}

找到BaseGame.ini

[/Script/Engine.GameSession]
MaxPlayers=16 ;就是你小子把if拐进来的?
MaxSpectators=2
MaxSplitscreensPerConnection=4
bRequiresPushToTalk=true

解决方案也就有了,修改配置文件或者直接使用cmd覆盖配置

net.MaxPlayersOverride 64

这个上限可以根据机器硬件决定