17
11

More than 3 years have passed since last update.

UE4でDedicated Serverを試す

Posted at

UE4のDedicated Serverをさわってみたので内容をメモしておきます。
試したUE4のバージョン:4.24.3

Dedicated Serverの実行方法

スタンドアロン実行

  • UE4をソースコードビルドしてプロジェクトから利用するようにする(Generate Visual Studio project filesが必要)。
  • 以下のTargetファイルを追加する(Generate Visual Studio project filesが必要)。
[プロジェクト名]/Source/[プロジェクト名]Server.Target.cs

using UnrealBuildTool;
using System.Collections.Generic;

public class [プロジェクト名]ServerTarget : TargetRules
{
    public [プロジェクト名]ServerTarget(TargetInfo Target) : base(Target)
    {
        Type = TargetType.Server;
        DefaultBuildSettings = BuildSettingsVersion.V2;
        ExtraModuleNames.Add("[プロジェクト名]");
    }
}
  • プロジェクト設定のMap&ModesのServer Default Mapでサーバー用のマップを指定する。
  • プロジェクトをビルドする。
  • .slnでDevelopment Serverを選択してビルドする。
  • [プロジェクト名]/Binariesの中にできた[プロジェクト名]Server*を[ビルドしたディレクトリ]/[プロジェクト名]/Binariesに配置して実行する。

参照リンク

プロジェクトから実行

プロジェクト設定のMap&ModesのServer Default Mapでサーバー用のマップを指定して以下のように実行する。
ビルドしなくてよいので確認のためには良さそう。

[UE4Editor.exeのパス] [プロジェクトのuprojectへのパス] Game -server -game -log

参照リンク

セッションとDedicated Server

CreateSession

参考リンクではクライアント側からOpenLevelなどでIPアドレスとポートを指定して接続するように書いているものが多いがその場合ボイスチャットは利用できない(こちらの記事参照)。
ボイスチャットを使うような場合にはCreateSessionしたセッションにJoinSessionする必要がある。

CreateSessionはそのまま用いると以下のようなエラーが発生して実行できない。

[2020.04.15-06.43.08:241][  0]LogScript: Warning: Script Msg: CreateSession - Invalid player state

Advanced Sessions PluginのCreateAdvancedSessionのブループリントノードを使う際にIsDedicatedServerにチェックを入れるか、PlayerNumを0にしてbIsDedicatedをtrueした設定をCreateSession時に渡すような処理をC++で独自実装する必要がある。
ちなみに、IsDedicatedServerというノードでDedicatedServerかどうか判定できるっぽい。

クライアントからのIP指定のセッション接続

OnlineSubsystemNull(+ WebSocketNetworkPlugin)で以下のような関数を作ってFBlueprintSessionResultをCreateAdvancedSessionに入力したら接続できてボイスチャットもできた。
PortはWebSocketNetworkPluginで指定したポート番号を指定。
TargetName、BuildUniqueIdは適当な値(testと0)でも接続できた。

#include "OnlineMyUtils.h"
#include "OnlineSessionSettings.h"
#include "OnlineIdentityNull.h"
#include "SocketSubsystem.h"
#include "Misc/DefaultValueHelper.h"

void UOnlineMyUtils::CreateSessionForJoin(const FString TargetName, const FString IpAddress, const int32 Port, const int32 BuildUniqueId, FBlueprintSessionResult& Result)
{
    Result.OnlineResult.PingInMs = 1;
    FOnlineSession* NewSession = &Result.OnlineResult.Session;
    FUniqueNetIdNull* UniqueId = new FUniqueNetIdNull(TargetName);
    NewSession->OwningUserId = MakeShareable(UniqueId);
    NewSession->OwningUserName = TargetName;
    NewSession->NumOpenPrivateConnections = 0;
    NewSession->NumOpenPublicConnections = 5;
    FOnlineSessionInfoNull* NullSessionInfo = new FOnlineSessionInfoNull();

    TArray<FString> IpAddressParts;
    IpAddress.ParseIntoArray(IpAddressParts, TEXT("."));
    int32 IpAddressInt = 0;
    if (IpAddressParts.Num() != 4)
    {
        UE_LOG(LogTemp, Warning, TEXT("Failed to read IpAddress"));
        return;
    }
    for (int i = 3; i >= 0; i--)
    {
        int32 IpAddressPartInt = 0;
        FDefaultValueHelper::ParseInt(IpAddressParts[3 - i], IpAddressPartInt);
        IpAddressInt += (IpAddressPartInt << i * 8);
    }

    NullSessionInfo->HostAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
    NullSessionInfo->HostAddr->SetIp(IpAddressInt);
    NullSessionInfo->HostAddr->SetPort(Port);
    NewSession->SessionInfo = MakeShareable(NullSessionInfo);

    NewSession->SessionSettings.NumPublicConnections = 5;
    NewSession->SessionSettings.NumPrivateConnections = 0;
    NewSession->SessionSettings.bShouldAdvertise = true;
    NewSession->SessionSettings.bIsLANMatch = false;
    NewSession->SessionSettings.bIsDedicated = true;
    NewSession->SessionSettings.bUsesStats = false;
    NewSession->SessionSettings.bAllowJoinInProgress = true;
    NewSession->SessionSettings.bAllowInvites = true;
    NewSession->SessionSettings.bUsesPresence = true;
    NewSession->SessionSettings.bAllowJoinViaPresence = true;
    NewSession->SessionSettings.bAllowJoinViaPresenceFriendsOnly = false;
    NewSession->SessionSettings.bAntiCheatProtected = false;
    NewSession->SessionSettings.BuildUniqueId = BuildUniqueId;

}

AWS EC2でのDedicated Serverの実行

ひとまずThirdPersonならt2.micro、素のAmazon Linux2で動作し接続できた。

GPUインスタンスの場合はGPUが利用される?
ちなみにGPUインスタンスでクライアントを実行するには以下のような設定をする必要があった。

$ sudo nvidia-xconfig --enable-all-gpus --allow-empty-initial-configuration --use-display-device=None --virtual=1920x1080
17
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
11