【UE5】マルチプレイにおいてプレイヤーが接続を切断したときの挙動

# 概要
マルチプレイにおいてプレイヤーが接続を切断したときの挙動を検証したものをまとめました。

検証のために利用したプロジェクトをGitHubにアップロードしました。

https://github.com/ogamita777/MultiDisconnected

何かしら気になる方は、ダウンロードして手元で試していただければと思います。

■確認した環境
- UnrealEngine：5.5.4
- エディタビルド構成：DebugGame Editor
- パッケージビルド構成：Development

■ゲームプレイ設定
〇エディタ
- Run Under One Process：true
- NetMode: PlayAsListenServer
- Play Number Of Clients(Number of Players)：2

〇パッケージ(コマンドライン引数)
- ListenServer環境：`TestMap?listen?bIsLanMatch=1 -windowed -ResX=960 -ResY=540`
- Client環境：`[IPアドレス] -windowed -ResX=960 -ResY=540`

# 検証

## 検証用プロジェクトについて
検証用プロジェクトでは画面左上にその環境のNetModeと各プレイヤーごとの下記項目の情報を表示するようになっております。
- PlayerId
- PlayerState
- Controller
- Pawn

![MultiDisconnectedの表示について.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/320de73c-28b7-4adb-9509-321e7ceb412c.png)

APawn::IsLocallControlled()の値は下記となっております。
||PlayerId256|PlayerId257|
|---|---|---|
|ListenServer環境|**true**|false|
|Client環境|false|**true**|

接続の切断は下記手順で行っております
- エディタ：コンソールコマンドから `open TestMap` を実行しTestMapに遷移してStandaloneモードになる
- パッケージ：ウィンドウをxボタン(Alt+F4)を押してプロセスを終了させる

## Clientのプレイヤーが接続を切断したとき
下記項目がListenServerの環境から即座にDestroyされます。IsValid()での判定がfalseになります。
- PlayerState
- Controller
- Pawn

||スクショ(ListenServer環境)|備考|
|---|---|---|
|切断前|![ListenServer環境で切断前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/cee1485e-095d-4c89-aaf8-756d68de3ad6.png)||
|切断後|![ListenServer環境で切断後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/0bf065c2-c2cc-4714-9d16-73c59c785a87.png)||

## ListenServerのプレイヤーが接続を切断したとき

Client環境は即座にGameDefaultMapに遷移します。

||スクショ(Client環境)|備考|
|---|---|---|
|切断前|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/84eae0c6-d3ac-444b-b661-79125020e141.png)||
|切断後|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/b7c2ebb2-54c5-4f5f-9c44-3952c90f00d6.png)|

■補足：GameDefaultMapについて
ゲームが起動したときに開かれるデフォルトのレベルです。
GameDefautMapは Edit > Project Settings > Map & Modes > GameDefaultMap から設定します。
![GameDefaultMap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29542/b9de698a-a6be-4afc-b4b8-46fd807bab2f.png)

UGameMapsSettings::SetGameDefaultMap() 関数を使うことにより、ゲーム起動後にGameDefaultMapを変更することが可能です。

```cpp
#include "GameMapsSettings.h"

UGameMapsSettings::SetGameDefaultMap(TEXT("/Game/Maps/TestMap"));
```

UGameMapsSettings::SetGameDefaultMap()を使うためには *.Build.cs に `EngineSettings` モジュールへの依存を追加することが必要です。

MultiDisconnected\Source\MultiDisconnected\MultiDisconnected.Build.cs
```csharp
using UnrealBuildTool;

public class MultiDisconnected : ModuleRules
{
	public MultiDisconnected(ReadOnlyTargetRules Target) : base(Target)
	{
		// 略
	
		PublicDependencyModuleNames.AddRange(
			new string[] {
				// 略
				"EngineSettings", // UGameMapsSettings::SetGameDefaultMap() を利用するために必要
			});

		// 略
	}
}

```
# 参考文献
 [【UE4】GameMode、GameState、PlayerState、PlayerControllerの関連を確認してみる - main() blog](https://www.main-function.com/entry/2017/11/22/220527)
 
 https://qiita.com/kelu_alfheim39/items/ddc131bbdea1ff93a21a

 [UE4 MultiPlayer Online Deep Dive: 実践編1 (Byking様ご講演) #UE4DD | ドクセル](https://www.docswell.com/s/EpicGamesJapan/5WXDDZ-ue4-multiplayer-online-deep-dive-1-byking-ue4dd)