【UQ1】当たると死ぬ棘【Multiplay】

UE1Needle

前回に引き続き、UnrealQuest1の課題の続きです。
1日目初級の残り、当たると死ぬ棘を作りました。

今回の成果
・MultiplayにおけるUI操作
・PlayerStateの使用
・Respawn処理
👇公式の解説動画。当たると死ぬ棘のところ。

「アンリアルクエスト-グレイマンからの5つの挑戦状-」特別生放送!【前編】

当たると死ぬ棘

BP_Needle

BP_ThirdPersonGameMode

EventGraph

PlayerStatusという名前で構造体を作成。
GameModeでは初期値を配列で作成し、PlayerStateに代入している。

MyPlayerController

CreateWidgetの前のBranchにより、Controllerを所有しているプレイヤーのみ処理を実行できる。
これを使わないと、Serverに同じWidgetが複数作成されてしまう。
ここではOnOwingClientのカスタムイベントと置き換え可能。ただし意味は少し違う。
RefleshWidgetのカスタムイベントを先ほどのBranchと置き換えることはできない。
RespawnPawnのイベントがRunOnServerであるので、そもそもServer以外の処理は実行されていないからである。

BP_ThirdPersonCharacter

EventGraph

Healthの変数
Healthの変数をPlayerStateとは別にキャラクターに作成した。
ダメージを受けてからUIに反映させるまでに時間がなく、
PlayerStateのHealthを直接使うとClientのUI反映に失敗したため。
PlayerState
BeginPlayされるタイミングが、PlayerStateが設定されるタイミングより早いようだ。
そのため、BeginPlayでキャストすると失敗する。
PlayerStateの使い方に困っていたが、これが原因だったようだ。
Delayを使って、無理やりタイミングをずらした。
ログイン
Clientの数が増えると、その増えたClientにおいて他のキャラクターが見えない現象がおきた。(たぶんBeginPlayが実行されていない。)
Clientのログインの遅れが問題だった。Delayで無理やりBeginPlayのタイミングをずらすことで一応解決。
死亡時の処理
OnOwingClientで死亡判定→死ぬイベント(Multicast)だと、Clientの死亡判定が他のプレイヤーに伝わらずラグドールにならない。
RunOnServerで死亡判定→死ぬイベント(Multicast)にすれば全プレイヤー視点で死んだPawnはラグドールになる。
HealthBarの更新は、頭上のものはMulticastで全プレイヤーに伝える。
WB_HealthBarの更新はDispatcherにより、そのキャラクターが紐づいているWidgetのみ更新される。
Respawn
今回はRestartPlayerを使わずに、CharacterとControllerに処理を書いている。あらかじめ用意されているRestartPlayerのようなノードは便利だが、中身を理解していないとカスタマイズするのが難しい。今回RestartPlayerを使うと少し不都合があったので自分で処理を作成した。

👇Blueprint

BP_ThirdPersonCharacter posted by anonymous | blueprintUE | PasteBin For Unreal Engine
No description provided

👇関数Change Color Random

👇RestartPlayerを使った場合の例

HealthBarWidget

頭上にWidgetComponentを追加した。
SpaceをScreen、Draw at Desired SizeをONにしてある。

下記のBPで、自分のプレイヤーが操作しているPawnの時のみ頭上のHealthBarを消した。
Pawnを所有しているプレイヤーと、所有していないプレイヤーで処理を分けることができる。

Get Controllerは、そのポーンを操作しているControllerをとってくる。
Get Player Controllerは、そのプレイヤーが操作しているControllerをとってくる。
自分のプレイヤーがそのPawnを操作しているときのみTrueになる。

WB_Player

Designer

Graph

WB_Player posted by anonymous | blueprintUE | PasteBin For Unreal Engine
No description provided

👇RespawnしてもWidgetは消えないので、Bindされたカスタムイベントは実行される。ただし、Characterは作り直されるので、Characterの変数は代入しなおす必要がある。

WB_Player

知識・考察

PlayerStateの設定や、Clientのログインを待つのにDelayを使った。
出来れば関数によって制御したい。

アクターを生成させたプレイヤー(server,clientなど)が持つらしい。
基本的にServerが所有権を持つらしい。
PlayerState,PlayerController,PlayerPawnは例外として各プレイヤーが所有権を持つらしい。
正直、まだよくわかってないみたい。

[UE4] マルチプレイでの所有権とRPC|株式会社ヒストリア
執筆バージョン: Unreal Engine 4.22 やあ、こんにちは! 今日はUE4でマルチプレイの勉強を始めると最初にぶち当たると思う所有権とRPCについてお話していくよ。 僕もマルチプレイ機能を一通り勉強した後、初めてマルチプレイゲーム開発を行っていたんだ。所有権とか結構色々な資料で注意されていたけど、余裕ぶっ...

👇この記事で、クライアントの所有権について少し説明してくれている。

ネットワーキングの概要
マルチプレイヤーに対応するネットワーク ゲームの設定

所有権というのは、PawnやPlayerControllerなどに対して、プレイヤーが持つものだと今のところ理解しておく。それでAuthorityとは別物。

いろいろ調べても、今の僕では理解できないのでこのくらいにしておく。

アクタとアクタの所有接続
マルチプレイヤー ゲームにおけるサーバーの役割の概要について説明します。

Dispatcherの使いどころがいまいちつかめないので少しまとめる。
他のBPでイベントを実行する場合を考える。
ここではCallする方を呼び出し元、イベントを実行する方を呼び出し先と呼ぶこととする。
カスタムイベント
呼び出し元が呼び出し先の参照をとる。1度のCallで1つの参照先に対してイベントを実行。
Dispatcher
呼び出し先が呼び出し元の参照をとりバインドして使用する。Dispatcher自体は呼び出し元に作成する。呼び出し元を複数のクラスが参照してバインドしていれば、1度のCallで複数のクラスでイベントを実行することが可能。多分。

Dispatcherのイメージ

考察
今回、WB_PlayerにおいてRespawn時にDispatcherを使用した。
BP_ThirdPersonCharacterが呼び出し元、WB_Playerが呼び出し先である。
Respawn時に古いPawnは消えるので、そのタイミングでWB_Playerで新しく生まれたPawnの参照をとってきて設定した。
このときの参照をとってくる方向の違いより、処理の実装のしやすさは変わると思う。
また、あらかじめBindしているということで実行の処理速度などにも影響はあるのかと推測。準備してるし、Dispatcherの方がちょっと速そう。

マクロ。
ServerはAuthority、ClientはRemote。
Serverが動かしているPawnでも、Clientが動かしているPawnでもAuthorityはServer。

ノード
中身

UEはServer主導型だから、常にServerはGameStateに対する権限を持つとのこと。Authorityと所有権は別物。

ネットワーキングの概要
マルチプレイヤーに対応するネットワーク ゲームの設定

参考

👇神。

👇すごく分かりやすい。

[UE4] マルチプレイでの所有権とRPC|株式会社ヒストリア
執筆バージョン: Unreal Engine 4.22 やあ、こんにちは! 今日はUE4でマルチプレイの勉強を始めると最初にぶち当たると思う所有権とRPCについてお話していくよ。 僕もマルチプレイ機能を一通り勉強した後、初めてマルチプレイゲーム開発を行っていたんだ。所有権とか結構色々な資料で注意されていたけど、余裕ぶっ...

👇かなり参考にした動画

Unreal Engine 4 Tutorial – Online Multiplayer Part 1: Replication

👇解説動画内で紹介されてたやつ。

Twitterしてます

ブログの更新をお知らせ

コメント

タイトルとURLをコピーしました