Unreal Engine初心者だけどマルチプレイしたい！ ~サーバビルド環境構築手順まとめてみた~

# 導入

Unreal Engine初心者がマルチプレイしようとしたとき、調べた内容をまとめていきます。
調べて出てくる情報は旧バージョンが多かったので、公式情報を参考にそれらをアップデートするような記事にしたいと思います。
最終的には、ローカルでDedicated Serverを動かして接続するところまでやります。

# 本題

基本的に、公式の[ネットワークの構築とマルチプレイヤー](https://docs.unrealengine.com/4.27/ja/InteractiveExperiences/Networking/)を参考に進めていきます。
なんだかんだで公式ドキュメントが優秀すぎるので、もっと詳しく知りたい場合はきちんと読み込んだ方が早いかもしれません。

## ネットワークモードとサーバータイプ
まずは、どんな環境が用意できるのかについてです。
公式ドキュメントでは、ネットワークモードとサーバータイプ別に４種類に分けられているようです。
（詳細は、[ネットワーキングの概要](https://docs.unrealengine.com/4.27/ja/InteractiveExperiences/Networking/Overview/)を参照)

Unreal Engineでは、PIE（Play In Editor）という機能でEditor上でプロジェクトを実行することができます。
この時、下記画像のような選択肢が出てくると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/f0b88f38-f8ec-212c-2f83-4d60564b874b.png)

これを参考に順番に説明していきます。


#### Standalone
Standaloneは、文字通り単体でゲームを実行することになります。この時、外部からの接続は受け付けません。
私のイメージでは、１人でプレイするノベルゲー等がこれだと思っています。
ちなみに、マルチプレイの設定をしていてもこの状態でPIEをすることができます。その場合は、サーバ側とクライアント側両方のロジックが実行されるので注意です。

#### Listen Server
Listen Serverは、マルチプレイを行う設定の１つで、プレイヤーの中にクライアントとサーバの両方を実行している端末が存在する状態です。あくまでイメージなのですが、通信対戦や協力プレイなどを行うゲームで、誰かが部屋をたてて他のプレーヤーがそこに入るイメージかなと私は思っています。
誰か１人がサーバとクライアント、他の人はクライアントのみを実行するので、サーバを別途用意する必要がなく、安価で実装が可能です。しかし、処理負荷が偏ったり、通信によるラグの問題、またはサーバを実行している人の不正の可能性などの問題があります。

#### Client
Clientも文字通り、クライアント側のロジックのみ動いている状態です。
Clientを実行している複数のユーザが、サーバに接続することでマルチプレイを実現できます。

このClientが接続するサーバは、Listen Serverの他にもう１つ種類があります。
それが、Dedicated Serverです。

#### Dedicated Server
Listen Serverが「クライアントと兼用のサーバ」だったのに対して、Dedicated Serverは「専用のサーバ」です。
サーバ側のロジックのみを実行（つまり、ローカルで必要な映像や音、入力などの機能はない）し、クライアントから接続することができます。
Listen Serverと異なり、別途サーバを用意する必要がありますが、Listen Serverが抱える問題点を解消することができます。

今回は、__Dedicated ServerとClientをビルドし、同じPC内でServerとClientを別々に実行して接続する__ ところまでやってみたいと思います。


## 実装
主に参考にしたのは、以下のリンクです。
試行錯誤した部分は、あえて取り消し線で変更していますので、参考にしていただければと思います。

https://docs.unrealengine.com/4.27/ja/InteractiveExperiences/Networking/HowTo/DedicatedServers/

https://youtu.be/AKiGajA7AXM

https://qiita.com/mechamogera/items/0b8719184bd088a165d0

### 環境
- Unreal Engine 4.26.2
- Visual Studio 2017
- OS : Windows 10

### 手順
1. EpicGamesのGithubにアクセスできるようにする
サーバービルドをするにあたってEditorだけではなく、VisualStudioを使ったソースビルドが必要になります。
なので、下記リンクを参考にGithubにアクセスできるように設定を行ってください。
https://www.unrealengine.com/ja/ue4-on-github?sessionInvalidated=true

2. 実行環境を整える
次に、自分が必要なバージョンのソースコードをダウンロードZipかCloneを行って取得し、そのフォルダを開きます。（参考リンク：https://docs.unrealengine.com/4.27/ja/ProgrammingAndScripting/ProgrammingWithCPP/DownloadingSourceCode/ ）
その中にある__Setup.bat__ を実行することで環境を整えてくれるようです。（かなり時間がかかります）
[この記事](https://norizn.hatenablog.com/entry/2020/06/02/222644)によるとEngine/Extras/Redist/en-us/UE4PrereqSetup_x64.exeも実行しておいた方がよさそうです。
最後に__GenerateProjectFiles.bat__を実行して__UE4.sln__が出来上がります。
__UE4.sln__をVS2017で開き、下記設定で右側にあるUE4のプロジェクトを右クリックし、ビルドを実行。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/3a95dfc6-b482-6998-107a-7995468a6658.png)
以上で環境構築は終了です。
VSは、サーバービルドまで一旦出てきません。

3. アプリのUnreal Engineの起動
参考にしたYouTubeではVisualStudioでやってますが、バージョン違いのせいか同様の環境ではなかったのでアプリの方でやりたいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/9b239b51-a82e-68fb-a7c3-6413f2d649c9.png)
4. テスト用のプロジェクトを作成
ThirdPersonのサンプルが使いやすいので、それを使っていきます。
新規プロジェクトのカテゴリ⇒ゲーム⇒サードパーソンを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/053200c7-3987-db79-a042-d603b2563297.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/71fe3248-f930-9667-f454-d1c0858b4a88.png)
最後の設定は下記のように設定（C++にするのを忘れないように）。名前は任意で。
私はプロジェクトを軽くしたいので「スターターコンテンツなし」を選択し、名前は「SandBoxProject」にしました。
いろいろ試したい方は「スターターコンテンツあり」でもよいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/4863ca81-57ad-1254-db39-f70dbbcef1d0.png)
プロジェクトが開けたら、初めての人はプレイボタンを押してWASDとSpaceでめぐってみてください。
このくらいのプロジェクトが簡単に作れるのは、なかなか感動しますよね。
ここでVSが開くかもしれませんが、一旦放置です。

5. Server側のレベルを作成
最終段階で接続をテストしたときに、確認しやすいように別のレベルを作っていきます。
右上にある「ファイル」をクリックし⇒新規レベル⇒Defaultを選択してください。
何もない世界ができるので、このレベルを判別できるようにServerという文字を表示させます。

6. 文字提示用ブループリント作成
左側にある緑入りの「追加/インポート」をクリック⇒ブループリントクラス⇒Actorを選択し、名前を「BP_ServerIndicator」に変更（BPはブループリントの略）
ダブルクリックで開くとEdit画面が開きます。

7. 文字の追加
コンポーネントを追加をクリックしてtextで検索
~~TextRenderができると思うので、ドラッグアンドドロップでDefaultSceneRootに重ねて、初期表示の球を消します。~~
これをやってしまうと、サーバー実行時にWarningが出ることが確認できましたので、非推奨です。消さなくても実行されたときに表示されることはありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/d2d85d8d-854c-635d-3c7a-1193fd53b118.png)
デフォルトの文字は文字化けしています。日本語フォントは、ちょっと設定変更が必要なようなので赤丸の部分に「Server」と記入。
TextRenderColorを適当にいじって色を変えてもよいと思います。私は、緑にしてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/8fe1666d-b5ff-0f0b-5c65-390b22fc1990.png)

8. Replicatesの設定
これはUEのサーバクライアント関係を理解する上で、__重要な設定__です。
詳細は[このリンク](https://docs.unrealengine.com/4.27/ja/InteractiveExperiences/Networking/Blueprints/)などを見てもらうとよいのですが、「Replicates フラグを true に設定しているアクタは、サーバーが自身と接続しているクライアントへ自動的に同期」することができます。この設定をすることで、同じサーバに接続している複数のクライアントに同じ情報が共有されます。
画像のように、コンポーネントタブで上の階層を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/c2c1be31-f24f-4d3e-281c-f171abd1b7d6.png)
詳細タブに「replicate」と入力すると、該当の設定が出てくるのでチェック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/17f8e53c-3df9-b785-b59b-c2cfb7f2f0ea.png)
コンパイルを押して問題なければ、保存をクリックし、もとのレベルが表示されてる画面に戻りましょう。

9. 文字の配置
「BP_ServerIndicator」をドラッグアンドドロップでレベル上に配置
緑で囲った青い矢印がキャラの向きなので、画像の赤で囲った部分のように数値を設定してもらうとうまくいくと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/789e0903-3150-d0c0-c8ed-db27b226b96c.png)
この段階で「現在のレベルを保存」を押して ~~適当なところに~~ 保存しましょう。
Mapsというフォルダを作成し、 __必ず__そこに保存しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/3c2f6f90-2e3a-468f-143b-8fe124790257.png)
これでレベルの準備は完了ですので、ビルドに向けた設定の変更を行っていきます。

10. もろもろ設定
編集からプロジェクト設定を開きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/827e4ed3-cf33-d7cc-7866-965e5d6e64f8.png)
マップ＆モード⇒~~遷移マップではなく~~サーバーのデフォルトマップのプルダウンから先ほど作成したレベルを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/082d8366-0cd7-d6c5-fdf7-89fe143b8dcc.png)
パッケージ化⇒赤まるで示した詳細タブを開き
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/c5df58f3-b0a3-fbfa-b92a-485c246c757d.png)
下記の項目を設定。
.umapという拡張子のものを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/f016ba9c-cc89-52a2-571c-f07861d4cc5a.png)
設定は完了です。
ここで、一旦すべてを保存してUE4を閉じましょう。
12. VisualStudioでサーバービルドするための準備
手順４で開いている人は、そちらに移動。もし開いてなければSandBoxProject.slnを開きます。
__ここからは「SandBoxProject」を適宜、自身が作成したProjectに置き換えて読んでください。__
「SandBoxProject/Source」に「SandBoxProject.Target.cs」があるので、同じ場所にそれをコピーし「SandBoxProjectServer.Target.cs」にリネームsyi
中身を下記のように変更（プロジェクト名を自分のものに変更）

    ```cs:SandBoxProjectServer.Target.cs
     // Copyright Epic Games, Inc. All Rights Reserved.
     using UnrealBuildTool;
     using System.Collections.Generic;
     
     public class SandBoxProjectServerTarget : TargetRules //Change this line according to the name of your project
     {
         public SandBoxProjectServerTarget(TargetInfo Target) : base(Target) //Change this line according to the name of 
     your project
         {
             Type = TargetType.Server;
             DefaultBuildSettings = BuildSettingsVersion.V2;
             ExtraModuleNames.Add("SandBoxProject"); //Change this line according to the name of your project
         }
     }
    ```
13. 新しい.slnファイルの作成
今回作成した.uprojectファイルを右クリックして「Switch Unreal Engine...」を選択し、プルダウンからSource Buildを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/56111269-fbc1-ed46-4dee-7f0e5cead829.png)
（これ以降でもしうまくいかなかったら「Generate Visual Studio project file」も実行）
14. ビルド
VSに戻り、環境外での変更のウィンドウが出たら「再読み込み」を選択
「Development Editor」を選択して、ウインドウ右側にあるソリューションエクスプローラに表示されているSandBoxProjectを右クリックしビルド
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/079d148f-de8a-68b6-964f-239e6dd15791.png)
さらに、「Development Server」を選択して、ウインドウ右側にあるソリューションエクスプローラに表示されているSandBoxProjectを右クリックしリビルド
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/704df832-1d09-67a5-8ae2-7b5418648cd8.png)
プロジェクトの「Binaries/Win64」フォルダに、「SandBoxProjectServer.exe」などのファイルがあれば問題ないです。

15. プロジェクトのパッケージ化
再度Unreal Engineを開き、アプリケーションファイルを作っていきます。
ファイル⇒プロジェクトをパッケージ化⇒Windows (64-bit)を選択して、プロジェクトをパッケージ化します。わかりやすいところに保存しましょう。
１０分ほどでClientアプリができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/352d74cf-5264-4cae-db55-6711481f1dae.png)
次に、ファイル⇒プロジェクトをパッケージ化⇒ビルド ターゲットを選択しSandBoxProjectServerと表示されているものを選択します。
そして、再度ファイル⇒プロジェクトをパッケージ化⇒Windows (64-bit)を選択して、プロジェクトをパッケージ化します。
同様に１０分ほどでServerアプリができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/bc1b632d-ccaf-0721-8ba2-1530a4e7c9dc.png)
16. 実行準備
これでやっと実行できる！と思っていたら、後一工夫必要です。
後の方でパッケージ化したWindowsServerファイルにある「SandBoxProjectServer.exe」というSeverアプリの方のショートカットを作成してください。
プロパティのリンク先の末尾に「-log」を追加。これによりログをcmdウィンドウで確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/3d1c6935-00cf-fc0c-9ad5-08550f1769b9.png)

17. 実行テスト
いよいよ実行です。
最初に起動するのは、先ほどのショートカットです。
なんだかいっぱい文字が出てきますが、動きが止まったらListenしている状態です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/84243f65-b8f0-69fe-8aa5-a968f8bf98d6.png)

次に、手順14で先にパッケージ化したときにできたWindowsNoEditorというファイルの直下にある「SandBoxProject.exe」を起動します。
サードパーソンのデフォルトの世界が出てきたら成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/83650f7e-4d04-b69d-b69d-d7beb9f54e15.png)

では、サーバにつないでみましょう。
アットマークのキーを押したら、コマンドモードになるので
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/75c0b039-b8ef-e4c7-11c0-4f0ad913bcbb.png)

```
open 127.0.0.1
```
と打ってエンターを押して、下記のように画面が変わったら成功です。
「127.0.0.1:7777」がデフォルトの接続先になります。ここで問題が起きたらファイアーウォールなどの設定を確認してみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/654650ef-fa56-3fde-c6eb-bd36171b4a51.png)

そして、Clientをもう一つ立ち上げて接続すると同じレベルに登場できるはずです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286446/efe0bfe8-35c1-c966-2cb1-c96b0683feef.png)


以上となります。
お疲れさまでした。