Unreal Engine (UE) Advent Calendar 2023の9日目の記事になります.
はじめに
UEで新しいことを学ぼうとする時に、まず最初に公式ドキュメントを読むことが多々あると思います。
今回はマルチプレイゲームを作りたいけどC++書くのはちょっと…という人のために、C++で書かれた公式ドキュメントの内容をBPだけでやってみました。
僕自身、勉強し始めたばかりなので不適切な点があるかもしれません。見つけた際はぜひご指摘いただけると幸いです。
レプリケートやRPC,所有権についての詳細は触れません.参考文献などをご参照ください.
環境
Windows10
UE5.3.2
目次
※公式ドキュメントの手順に沿って進めます
基本設定
新規プロジェクトをサードパーソンテンプレートで作成します。
以下の点を確認してください。
- BPプロジェクトであること
- スターターコンテンツが含まれていること
- デスクトップをターゲットにしていること
プロジェクトを作成してエディタを開くことができたら、PlayerStartを複製しておきます。
ここまで設定できたら一度起動してみましょう。「NewEditorWindow(PIE)」で起動するのがおすすめです.ウィンドウが2つ出て、それぞれキャラクターを操作できるようになっています。CharacterMovementコンポーネントで移動を制御しているだけで、キャラクターの位置が同期されています。
実行したあとMessageLogに以下のようなWarningが出るかもしれません.
その場合,「Editor Preferences→Level Editor→Play Credentials」を開きます.「Credentials」にプレイヤーの数だけ追加します.情報は適当で大丈夫です.
RepNotifiesを使用してプレイヤーのヘルスをレプリケートする
キャラクターのHPを設定していきます。
BP_ThirdPersonを開いてください。
最大HPを表す「MaxHealth」と、現在HPを表す「CurrentHealth」をfloat型で作成します。今回「MaxHealth」の初期値は100にしました.
「CurrentHealth」は他プレイヤーと同期する必要があるのでレプリケートの設定をします。
RepNotifyに設定すると「OnRep_(変数名)」という関数が自動的に作られます.変数の値が変更されたときに実行したい処理を書きます.
今回は残りのHPをPrintStringで表示する関数を用意し,ダメージを受けたときに実行するようにします.
「OnHealthUpdate」という関数を作成し,以下のように組みます.
「OnRep_CurrentHealth」で「OnHealthUpdate」を呼び出します.
プレイヤーのHPを初期化するために,「BeginPlay」イベントで「SetCurrentHealth」を呼び出します.しかしこのまま呼び出してもクライアント側でしか実行されず,サーバーには反映されません.そのためサーバーで実行させるためのイベントを用意します.カスタムイベントを作成して「Replicates」を「Run on Server」にします.Reliableにチェックを入れることで,処理負荷などでRPCが送信されなかったときに再送信するようになります.
作成したイベントを「BeginPlay」で呼び出します.
プレイヤーをダメージに反応させる
次にプレイヤーがダメージを受けた時の処理を書いていきます。
BP_ThirdPersonを開いてください。
HPのゲッターとセッターを作成します。
変数はprivateにして、外部からはゲッターとセッターを通じて
アクセスできるようにします。
セッターに関しては、サーバーだけが値の変更が可能であるようにしておくべきです。そのため「Switch Has Authority」ノードを使用して、関数の実行者がサーバーの時だけ処理を行うようにします。
次にプレイヤーへダメージを適用する処理です.ここでは「AnyDamage」ノードを使用します.ダメージを通知する「Apply Damage」ノードや「Any Damage」ノードはサーバーで実行されるようになっています。
レプリケーションで発射物を作成する
まず発射物のActorを作成します.名前は「BP_MultiPlayProjectile」としました.
[画像]
作成したBPを開いて,以下のコンポーネントを追加します.
- StaticMesh
- SphereCollision
- CascadeParticleSystem
- ProjectileMovement
ParticleSystemの設定は以下のようになっています.StarterContentにある爆発エフェクトを使用するためにCascadeのParticleSystemを使用しています.発射物を生成したと同時にエフェクトが再生されないように,「AutoActivate」をfalseにしています.
コンポーネントを追加したら,衝突時にプレイヤーへ与えるダメージ用の変数を作成します.
アクターをレプリケートするために,「ClassDefaults→Replication→Replicates」にチェックを入れます.
「ProjectileMovement」コンポーネントを以下のように設定します.
発射物によるダメージを作成する
BP_MultiPlayProjectileのEventGraphを開いてください.
発射物がプレイヤーに衝突したらダメージを与えるようにします.今回は「OnComponentBeginOverlap」を使用します.
アクターを破棄する際にエフェクトを再生します.SEなどを追加しても良いです.
発射物を発射する
特定のキーを押したら発射物を発射するようにします.せっかくなのでEnhanced Inputを使用してみます.まずInputActionを新たに作成します.
Triggersの要素を追加して,Pressedを設定します
「Content→ThirdPerson→Input→IMC_Default」を開き,先ほど作成した「IA_Fire」を登録します.今回はFキーを押したら発射するようにします.
ここまでできたらBP_ThirdPersonを開いて処理を書いていきます.
次発射できるようになるまでの時間と,発射中のフラグの2つの変数を追加します.
発射用のイベントを用意します.発射物を生成するイベントだけ「Run on Server」に設定します.サーバー上で生成することで,他クライアントにレプリケートされます.
Fキーを押したときに「StartFire」イベントが呼び出されるようにします.
これで完成です.実行してみましょう.
おわりに
最後まで読んでいただきありがとうございました!
ざっくりとした説明だったので,補足必要なところや不備があればコメントいただけると幸いです.
またこういう風にした方がいいなど改善案も受け付けています.
参考文献
※↓UE4.27のページですが内容は問題ありません
※↓こちらにドクセルのリンクもあります