Weitere ähnliche Inhalte Ähnlich wie UE4でマルチプレイヤーゲームを作ろう (20) Mehr von エピック・ゲームズ・ジャパン Epic Games Japan (20) UE4でマルチプレイヤーゲームを作ろう28. #UE4 | @UNREALENGINE
ドキュメント
⚫ UE4公式ドキュメント
⚫ https://docs.unrealengine.com/jp/index.html
⚫ 'Unreal Engine 4' Network Compendium
⚫ http://cedric-neukirchen.net/Downloads/Compendium/UE4_Network_Compendium_by_Cedric_eXi_Neukirchen.pdf
⚫ EpicWiki
⚫ https://wiki.unrealengine.com/index.php?title=Main_Page
⚫ DedicatedServerGuide
⚫ https://wiki.unrealengine.com/index.php?title=Dedicated_Server_Guide_(Windows_%26_Linux)
⚫ 他多数
⚫ SlideShare
⚫ https://www.slideshare.net/EpicGamesJapan/online-multiplay-game-design
35. #UE4 | @UNREALENGINE
兼業サーバー - ListenServer
プレイヤーの誰かがサーバーを兼ねる方法
コンソールゲームでよく利用されます
⚫ メリット
⚫ サーバーの維持費がかからない
⚫ デメリット
⚫ サーバー役のCPU/通信負荷が高く、通信品質が求められる
⚫ サーバー役とクライアントで有利不利の差がどうしても出てしまう
⚫ サーバー役がいなくなると解散になってしまう
⚫ NAT問題(いわゆるルーター越え問題)
37. #UE4 | @UNREALENGINE
専業サーバー - DedicatedServer
余計なものを削ぎ落した専用サーバーを、コンピューターに配置して実行します
製品版ではデータセンターに配置されます
プレイヤーはすべてクライアントとして接続されます
⚫ メリット
⚫ グラフィックスやサウンドなどの処理を省けるので負荷が低い
⚫ NATの問題が無く、通信障害などが無い限り接続に成功する
⚫ プレイヤー間の優劣が無い
⚫ データセンターへの経路はよく調整されており通信品質が期待できる
⚫ デメリット
⚫ 運用コストがかかる
49. #UE4 | @UNREALENGINE
Epic Online Service
Unreal Engine とは別にエピックゲームズが提供している
ゲームサーバーサービス
● 特徴
● 一般的にプラットフォーム向けのSDKが提供している、マッチング、ユーザー管理、分析、
ランキングなどのサービスをプラットフォームに依存しない形(クロスプラットフォーム)で
提供し、無料で利用できます
● 現在提供されている機能はまだ一部で、鋭意開発中です
● オープンソースソフトウェアではありません
● このサービスを利用するに当たって、UE4を使う必要はありません
他のゲームエンジンやミドルウェアを使用しないタイトルでも問題無く利用可能です
● サーバーは弊社が管理しており、この利用料も発生しません
● DedicatedServerのホスティングは含まれません
● 詳しくはEOSのポータルをご覧ください
● https://dev.epicgames.com/ja/services
54. #UE4 | @UNREALENGINE
Play In Editor (PIE)
エディタ上でメモリに読み込まれているアセットを
利用できるので、素早くマルチプレイでのレベルを
確認するのに有効です。
エディタのプロセス上で指定した分のプレイヤー
(+DedicatedServer)のワールドを複数生成し
直列に処理します。
※UseSingleProcess : ON 時
55. #UE4 | @UNREALENGINE
New Editor Window 実行の注意点
⚫ シームレストラベルは無視されます
⚫ ウィンドウを閉じるとすべてのセッションが終わります
⚫ Statsファイルやカウンタがすべてのクライアント分まとまってしまいます
64. #UE4 | @UNREALENGINE
Auto Connect To Server OFF
NewEditorWindow では、 指定したプレイヤー数分、ネットワーク非接続の状態
でクライアントが起動します。以下の手順でログインのテストが可能です。
1.サーバーになるウィンドウで?listen オプション付きでレベル移動
2.クライアントウィンドウで open 127.0.0.1 と入力しサーバーに接続
open ?listen
または
open ThirdPersonExample?listen
open 127.0.0.1
72. #UE4 | @UNREALENGINE
文字で起こしてみる
1. UWorld::Tick
1. UNetworkDriver::TickDispatch
1. Packet受信 > Bunchに分解
1. BunchをActorChannelに流して、プロパティをレプリケート+RPCの実行
2. PostReceivedBunch > RepNotifyを処理
2. タスクグラフのループ
1. RPCの呼び出し (ServerMoveなど)
3. UNetworkDriver::TickFlush
1. BuildConsiderList 考慮するべきNetActorのリストを作る
2. Connection毎のループ
1. PrioritizeActors
2. ProcessePrioritizedActors
1. ActorChannel毎にプロパティの差分を抽出してBunchを書き出す
3. Connection毎のループ - UNetConnection::Tick
1. UNetConnection::FlushNet()
こちらもお勧め https://docs.unrealengine.com/ja/Gameplay/Networking/Actors/ReplicationFlow/index.html
91. #UE4 | @UNREALENGINE
ローカルか否か Server Client
PlayerController
&Pawn
Role Authority AutonomousProxy
RemoteRole AutonomousProxy Authority
Replicateが設定されて
いるActor
Role Authority SimulateProxy
RemoteRole SimulateProxy Authority
Replicateが設定されて
いない静的なアクター
Role Authority None
RemoteRole None Authority
Replicateナシ
ローカルで生成
Role Authority Authority
RemoteRole None None
99. #UE4 | @UNREALENGINE
休眠状態 NetDormant/NetDormancy
サーバー上でAActror::SetNetDormancyなどを利用して休眠状態を設定し、
レプリケーション処理のチェック対象から除外し負荷を軽減する最適化用の機能
実際に休眠状態に入るためには、レプリケートするべきプロパティが無い状態を
作る必要があります。
100. #UE4 | @UNREALENGINE
休眠状態 NetDormancy
一度休眠状態に入ったアクターはFlushNetDormancy()が呼ばれると
眠りから覚めます
この関数ははプロパティの変更などによってエンジンから呼び出されます
つまり休眠状態はある程度自動で動作します
一定時間変更が加わらない可能性があるアクターは休眠状態への移行を要求する
ことでレプリケーションの処理時間を軽減することができます。
プロパティの変化が激しいアクターに適用すると状態移行チェックの負荷が加わ
ってしまうだけになります
101. #UE4 | @UNREALENGINE
休眠状態の設定値
備考
DORM_Never DORM_Awakeと同等
DORM_Awake(Default) 休眠状態なら復帰し休眠状態に入らない。
DORM_DormantAll 休眠状態へのチェックを行い条件を満たせば休眠状態に移行する
DORM_DormantPartial Connection毎に挙動を切り替えることができる模様
AActor::GetNetDormancyの実装が必要
DORM_Initial 初期状態でNetActorListから除外され休眠状態に入る
FlushNetDormancyが呼ばれるとDORM_DormantAllに移行する
105. #UE4 | @UNREALENGINE
関連性 NetRelevancy
サーバー上でConnection毎に距離などを考慮して
そのアクターをレプリケートするべきか判断する仕組み。
レプリケーション処理の中では、アクターが列挙されて優先順位別にならんだあ
と、実際にプロパティを調べる直前にAActor::IsNetRelevantForを通じてチェッ
クされます。
NetActor
リスト生成
優先順位
ソート 関連性チェック
変更差分の取得と
送信
110. #UE4 | @UNREALENGINE
Pawn
P:4 t:1 = 4
Pawn
P:4 t:1 = 4
A
P:1 t:4 = 4
B
P:1 t:3 = 3
C
P:1 t:2 = 2
C
P:1 t:1 = 1Frame 1
Pawn
P:4 t:1 = 4
Pawn
P:4 t:1 = 4
A
P:1 t:1 = 1
B
P:1 t:4 = 4
C
P:1 t:3 = 3
C
P:1 t:2 = 2Frame 2
Pawn
P:4 t:1 = 4
Pawn
P:4 t:1 = 4
A
P:1 t:2 = 2
B
P:1 t:1 = 1
C
P:1 t:4 = 4
C
P:1 t:3 = 3Frame 3
Pawn
P:4 t:1 = 4
Pawn
P:4 t:1 = 4
A
P:1 t:3 = 3
B
P:1 t:2 = 2
C
P:1 t:1 = 1
C
P:1 t:4 = 4Frame 4
送信! 次のTickに持ち越し
115. #UE4 | @UNREALENGINE
Min Net Update Frequency とは
MinNetUpdateFrequencyは「AdaptiveNetUpdateFrequency」が
有効なときだけ使われるパラメータです
この機能はデフォルトでOFFです
これは実際にレプリケートされた間隔の
実績値に合わせて、
Min~とNetUpdateFrequencyの間で
パラメータを自動調節する機能です
133. #UE4 | @UNREALENGINE
PlayerController Advanced
ServerRPCやClientRPCが特定の対象だけに届くのは、
有効なNetConnectionをPlayerプロパティを持っているかどうかです
PawnはPlayerControllerに所持(Possess)されている場合のみ所持元の
PlayerControllerがもつNetConnectionを使えます
( APawn::GetNetConnection & APlayerController::GetNetConnection 参照 )
148. #UE4 | @UNREALENGINE
動かしてみると・・・
Server: PlayerCameraManager1
Client 1:
Server: ThirdPersonCharacter
Client 1: ThirdPersonCharacter1
Server: Linear_Stair_StaticMesh
Client 1: Linear_Stair_StaticMesh
Server: Wall11
Client 1: Wall11
Server: LeftArm_StaticMesh
Client 1: LeftArm_StaticMesh
Server: PlayerState1
Client 1: PlayerState
Server: GameNetworkManager
Client 1:
Server: AbstractNavData-1
Client 1:
Server: WorldInfo
Client 1: WorldInfo
送り先のワールドに
存在しないアクターは
NULLになる
153. #UE4 | @UNREALENGINE
受信返答OK/NG - ACK / NAK
ACK - ACKnowledgement
NAK - Negative-AcKnowledgement
ネットワーク処理の中での一般的な単語で
UE4の専門用語ではありません
パケットが受信されたかどうかを表します
ビット列の形でパケットのヘッダに書き込まれていて、重要なパケットのやり取
りが行われたかどうかの確認や、Reliableなやり取りの再送信などに利用される
ます
166. #UE4 | @UNREALENGINE
⚫ アクターの状態を表す変数
⚫ 途中参加したときに復元しないと困るプロパティ
⚫ 10秒後に失われては困るもの
⚫ ライフ
⚫ 所持アイテム
⚫ キャラクターの見た目
こういうものは変数の複製向け
167. #UE4 | @UNREALENGINE
変数の書き換えは慎重に
//またはAutonomousProxyからは自動でServerRPCを飛ばすなど
Void ASampleActor::SetReplicatedVariable( float InValue )
{
if( HasAuthority() )
{
ReplicatedValue = InValue;
return;
}
check( Role == ROLE_AutonomousProxy ); //Simulate や None の場合サーバーRPCは送信できない
ServerSetReplicatedVariable( InValue ); //ServerRPC
}
//アクセサを経由して変数を操作するのをオススメします
Void ASampleActor::SetReplicatedVariable( float InValue )
{
check( HasAuthority() ); //不正な操作が起きないように
ReplicatedValue = InValue;
}
175. #UE4 | @UNREALENGINE
移動情報の送信
void ServerMove(
float TimeStamp,
FVector_NetQuantize10 InAccel, //量子化された加速度 精度は 1mm/s^2
FVector_NetQuantize100 ClientLoc, //量子化された位置 精度は 0.1mm
uint8 CompressedMoveFlags, //移動フラグ ジャンプ上昇中とか
uint8 ClientRoll, //オイラー表現 ControlRotationのRoll
uint32 View, //オイラー表現 ControlRotationのYawとPitch
UPrimitiveComponent* ClientMovementBase,//どのプリミティブ上に立っているか
FName ClientBaseBoneName, //MovementBaseのどのBoneに立っているか
uint8 ClientMovementMode //クライアント上でのMovementMode
);
176. #UE4 | @UNREALENGINE
void ServerMove(
float TimeStamp,
FVector_NetQuantize10 InAccel, //量子化された加速度 精度は 1mm/s^2
FVector_NetQuantize100 ClientLoc, //量子化された位置 精度は 0.1mm
uint8 CompressedMoveFlags, //移動フラグ ジャンプ上昇中とか
uint8 ClientRoll, //オイラー表現 ControlRotationのRoll
uint32 View, //オイラー表現 ControlRotationのYawとPitch
UPrimitiveComponent* ClientMovementBase,//どのプリミティブ上に立っているか
FName ClientBaseBoneName, //MovementBaseのどのBoneに立っているか
uint8 ClientMovementMode //クライアント上でのMovementMode
);
移動情報の送信
クライアント上のワールド時間
加速ベクトル
カメラの向き
ボタン入力など
177. #UE4 | @UNREALENGINE
void ServerMove(
float TimeStamp,
FVector_NetQuantize10 InAccel, //量子化された加速度 精度は 1mm/s^2
FVector_NetQuantize100 ClientLoc, //量子化された位置 精度は 0.1mm
uint8 CompressedMoveFlags, //移動フラグ ジャンプ上昇中とか
uint8 ClientRoll, //オイラー表現 ControlRotationのRoll
uint32 View, //オイラー表現 ControlRotationのYawとPitch
UPrimitiveComponent* ClientMovementBase,//どのプリミティブ上に立っているか
FName ClientBaseBoneName, //MovementBaseのどのBoneに立っているか
uint8 ClientMovementMode //クライアント上でのMovementMode
);
移動情報の送信
位置(不正移動チェック用)
地面(不正移動チェック用)
移動モード(不正移動チェック用)
地面の関節名(不正移動チェック用)
189. #UE4 | @UNREALENGINE
Unreal Engine Tech-blog
https://www.unrealengine.com/ja/tech-blog/replication-graph-overview-and-proper-replication-methods?lang=ja
198. #UE4 | @UNREALENGINE
結果 stat game
● Server ReplicateActrors Time
● 138ms
● Prioritize Actors Time
● 98ms
● Consider Actors Time
● 38ms
● Replicate Actor Time
● 70calls 0.5ms
● 5つのクライアントは60fpsで動作
213. #UE4 | @UNREALENGINE
組み込みノード : GridSpatialization2D
アクターの現在位置にあわせて
グリッドに投入します
境界付近のアクターは2つ以上のセルに
投入されます
ActorのCullDistanceSquaredの値を参照して
投入範囲を設定します
214. #UE4 | @UNREALENGINE
組み込みノード : Grid_Dynmic
移動するアクターはGridSpatialization2D下のDynamicに配置します
毎TickのPrepareForReplication()で、
格納されるセルの範囲が変わっていないかチェックが入ります
※50000actorで20ms以上かかります
移動するアクターが極端に多い場合は、ここを仕様に合わせて調整したり
独自実装をおススメします。