ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
Unreal Engine 5(UE5)でプレイヤーのHPのようなゲーム変数を置く場所は、「そのデータがどのスコープで生き、いつ消えるべきか」で決めるのが基本です。結論から言うと、戦闘中のHPのようにキャラクターの実体に紐づき、毎フレーム変化しうる値は Character(または Pawn)に、プレイヤー単位で持ち、マルチプレイで他クライアントにも見せたい値は PlayerState に置くのが定石です。「レベルをまたいで保持したい」「セッション全体で1つだけ持ちたい」といった要件が出てきて初めて GameInstance や GameState、保存なら SaveGame を検討します。本記事では各クラスの役割を比較し、HPを具体的にどこへ置くべきかを設計観点で整理します。
| この記事の要点 |
|---|
|
変数の置き場所候補とその役割
UE5には用途の異なるベースクラスが用意されており、それぞれ「生存期間」と「ネットワーク上での扱い」が異なります。まず全体像を比較します。
| クラス | 主な役割 | 生存期間 | マルチプレイでの扱い | HPに向くか |
|---|---|---|---|---|
| Character / Pawn | 操作対象の「体」そのもの。移動・当たり判定・戦闘処理を持つ | そのレベルにスポーンしている間。デスポーンや破棄で消える | 各クライアントに複製される。値はレプリケート可能 | その場の現在HPに最適 |
| PlayerState | 「プレイヤー」という人格に紐づく情報(スコア、名前、チーム等) | そのプレイヤーが接続している間。Pawnが死んでも残る(レベル遷移時は再生成されうる) | 全クライアントに複製される。他プレイヤーからも参照しやすい | プレイヤー単位で持つHPに最適 |
| GameState | 試合・ワールド全体の状態(残り時間、現在のラウンド、全体スコア等) | そのレベルが読み込まれている間 | サーバーで保持し全クライアントへ複製 | 個人のHPには不向き |
| GameMode | 試合のルール・勝敗判定・スポーン制御 | そのレベルが読み込まれている間 | サーバーのみに存在。クライアントから直接参照不可 | HPの保持先には不向き |
| GameInstance | アプリ起動からゲーム全体を貫く単一のオブジェクト | ゲーム起動中ずっと。レベル遷移をまたいでも生存 | 各マシンにローカル。自動レプリケーションの仕組みはない | レベル跨ぎの引き継ぎ用途のみ |
| SaveGame | ディスクへ永続保存するためのデータ入れ物 | 明示的に保存/読み込みした内容がファイルとして永続 | ネットワークとは無関係(保存処理は別途実装) | セーブ対象の値の保存先 |
表のとおり、同じ「HP」でも戦闘中の生々しい値とセーブして次回も引き継ぐ値では適した置き場所が違います。1つのクラスにすべてを詰め込もうとすると、後でマルチプレイ対応やセーブ機能を足すときに破綻しやすくなります。
HPはどこに置くのが最適か
最も判断に迷うHPについて、典型的なケースごとに整理します。
基本(シングルプレイ・1体のキャラ):Character / Pawn
プレイヤーが操作する1体のキャラクターのHPであれば、その Character クラスに CurrentHealth / MaxHealth を持たせるのが最もシンプルです。理由は明快で、ダメージを受ける主体・回復する主体・破壊される主体がすべてそのキャラクター自身だからです。TakeDamage や ApplyDamage の流れと同じクラス内で完結し、HPバーUIもそのPawnを参照すれば済みます。データと振る舞いが同じ場所にある、という意味で素直な設計です。
プレイヤー単位で持ちたい・マルチプレイ:PlayerState
次の条件のいずれかが当てはまるなら、HPを PlayerState に置くことを検討します。
- 他のプレイヤーからもHPを見たい(味方のHPバーを表示する等)。
PlayerStateは全クライアントに複製されるため、他者の値を参照しやすい。 - Pawnが破棄されてもHPに関する状態を保ちたい。Pawnは死亡で破棄されうるが、
PlayerStateはプレイヤーの接続が続く限り残るため、「最大HPのアップグレード値」のようなキャラの実体に依存しない属性の保持先に向く。 - キャラクターを乗り換える(憑依し直す=Possess)設計で、HPをキャラではなくプレイヤーに紐づけたい。
実務では「現在HPはCharacter、最大HPやプレイヤー恒久ステータスはPlayerState」のように役割分担する構成もよく使われます。どちらか一方が常に正解ということはなく、要件に合わせて分けるのが現実的です。
マルチプレイ時の考慮(レプリケーション)
マルチプレイでは「どこに置くか」と同じくらい「どう同期するか」が重要です。UE5のネットワークモデルでは原則として次のルールが効いてきます。
- 権威はサーバーにある。HPの値はサーバー側で変更し、そこからクライアントへ複製するのが基本。クライアントが勝手に書き換えた値はチートの温床になり、同期もずれる。
- 複製したい変数は
Replicated(または値変化時に処理を走らせたい場合はRepNotify)として設定する。HPバーの更新はこのRepNotify経由で行う構成が一般的。 PlayerStateやCharacterは複製の仕組みを持つが、GameModeはサーバーのみに存在するためクライアントから直接参照できない。HPの保持先としては不適切。
「PlayerState に置いてレプリケーションを有効化し、値の変更はサーバーで行う」——マルチプレイのプレイヤーHPはこの形が出発点になります。なお複製フラグの細かな指定(DOREPLIFETIME の条件等)はバージョンや実装で差があるため、正確な記述は公式ドキュメントの確認を推奨します。
セーブが必要なら何を保存するか
「次回起動時もHPを引き継ぎたい」場合、HPを保持しているクラスをそのままディスクに書けるわけではありません。Character や PlayerState はランタイムの実体であり、レベルを抜ければ破棄されます。永続化したいときは SaveGame を継承したオブジェクトを用意し、保存したい値だけを詰め替えて SaveGameToSlot 等で書き出します。
- 保存対象は通常、「数値・状態」だけ(現在HP、最大HP、所持アイテムID、進行フラグ等)。アクターそのものは保存しない。
- ロード時は
SaveGameから読み出した値を、スポーンし直したCharacter/PlayerStateに書き戻す。 - セーブとランタイムは別レイヤーとして分けて考えると、設計が崩れにくい。
よくある落とし穴
| 落とし穴 | 何が起きるか・どう避けるか |
|---|---|
| GameInstanceに何でも置く | 「消えないから便利」と現在HPまでGameInstanceに置くと、各クライアントローカルで複製もされず、戦闘中のリアルタイム同期に使えない。GameInstanceはレベル跨ぎで引き継ぐ最小限の値に留める。 |
| レベル遷移で消える場所に永続データを置く | Character や GameState はレベルを抜けると破棄される。次のレベルへ引き継ぎたい値をここだけに持つと消える。引き継ぎは GameInstance 経由、永続は SaveGame で。 |
| 複製(レプリケーション)漏れ | 変数を Replicated にし忘れる/クライアント側で値を書き換える、と他プレイヤーにHPが伝わらない・値がずれる。値はサーバーで変更し、UI更新は RepNotify で行う。 |
| GameModeをクライアントから参照しようとする | GameMode はサーバーのみに存在するため、クライアント側のBPから取得しようとすると無効になる。全員が参照すべき状態は GameState に置く。 |
FAQ
Q. シングルプレイならとりあえずCharacterにHPを置けばよい?
A. はい、それで問題ありません。シングルプレイで1体のキャラを操作するだけなら、Character に現在HP・最大HPを持たせるのが最もシンプルで保守しやすい構成です。後からマルチプレイやセーブが必要になった時点で、PlayerStateやSaveGameへの分離を検討すれば十分です。
Q. マルチプレイで味方のHPバーを表示したい。どこに置く?
A. PlayerState が向いています。PlayerStateは全クライアントへ複製されるため、各プレイヤーが他プレイヤーのPlayerStateを参照してHPバーを描画できます。値の変更はサーバー側で行い、複製を有効にしてください。
Q. レベルをまたいでHPを維持したい場合は?
A. Character や PlayerState はレベル遷移で破棄・再生成されうるため、引き継ぎたい値は GameInstance に退避し、次のレベルで新しいキャラへ書き戻す流れにします。さらにアプリ終了後も残したいなら SaveGame でディスクへ保存します。ただし各クラスの破棄・再生成の細かな挙動はバージョンや構成で差があるため、最終的な仕様は公式ドキュメントでの確認を推奨します。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
- 床の上に乗ったらイベントを発生させる方法
- OverlapAllDynamicとOverlapAllの違い
- タイトル画面を作る方法
- サードパーソンテンプレートでのキャラクター表示の仕組みと非表示にする方法
- ボタンに文字を記載する方法
- Event ActorBeginOverlapとOn Component Begin Overlapの違い
- キャラクターに特定のオブジェクトとの当たり判定を付ける
- 特定のオブジェクトに触れたとき、キャラクターが倒れるようにする
- 動いているオブジェクトに静止しているキャラクターが当たり判定を持たない原因と解決方法
- 「On Component Hit」に「Cast To ~」で複数のクラスを指定する方法
- Blenderファイルをインポートする方法
- 鏡を作成する方法
- レベルブループリントでキャラクターの出現を設定する方法
- サードパーソンテンプレートにおけるキャラクター出現の定義
- アイテムに近づいたらボタンを押してイベントを発火させる方法
- 画面の中央にメッセージを表示する方法
- どこからでも呼び出せるカスタムイベントを作成する方法
- カスタムイベントに引数を追加する方法
- 「Get Overlapping Actors」から特定のクラスの場合のみ処理を実行する方法
- オブジェクトに近づいている間だけメッセージを表示する方法
- PCの画面を操作するUIを作る方法
- コンテンツブラウザに画像を追加する方法
- SetInputMode_UIOnlyを取り消す方法
- 特定の画像の上にマウスカーソルを置いたら手マークにする方法
- オブジェクトがアウトライナーで選択できない原因と解決策
- PlayerStartを作成する方法
- メニュー画面を作成して開く方法
- 「Esc」キーを押してメニュー画面を開く方法
- イベントの「On Clicked」と「On Pressed」の違い
- 「Set Input Mode」の種類と使い方
- 「Set Game Paused」の使い方と詳細解説
- Motion Matchingとは?
- 「GameMode」と「GameModeBase」の違い
- マップに配置したTargetPointを取得する方法
- TargetPointにタグをつけて取得する方法
- Spawnしたインスタンスがイベントを実行する方法
- 特定の時間ごとに処理を実行する方法
- 数値をランダムで出力する方法
- ThirdPersonテンプレートでキャラクターの移動を歩くように変更する方法
- MaxWalkSpeedを変更する方法
- しゃがむ動作を導入する方法
- キャラクターのアニメーションを設定する方法
- 導入済みのプラグインを確認する方法
- Motion Matchingの導入と必要なプラグイン
- プレイヤーを非表示にする方法
- カメラを傾ける角度を制限させる方法
- 配列からランダムに重ならない要素を特定の数取得する方法
- カメラの映す画面に文字やエフェクトを付ける方法
- キャラクターやメッシュを非表示にした際にカメラが移動しなくなる問題の解決方法
- プライマリーデータアセットを活用する方法
- プレイヤーのHPといった変数を定義する最適な場所
- カメラに映った画面をスクリーンショットとして保存する方法
- ゲーム内のカメラ映像を保存して再表示する方法
- HighResShot を使って高解像度の画像を保存する方法(UE5)
- HighResShotで保存した画像のファイル名を取得する方法
- SceneCapture2DとFrameGrabberの画像保存方法の比較
- SceneCapture2Dを使用して画像を保存・取得する方法
- HighResShotとTake High Res Screenshotの違い
- ゲーム終了ボタンを作成する方法
- 「Save Game To Slot」の戻り値がfalseになる問題の解決方法
- 画面上にメッセージを指定された時間表示させる方法
- シェーダコンパイル時間を短縮する方法
- 「Take High Res Screenshot」実行時に「シェーダをコンパイル」に長時間待たされる問題とその解決策
- データベースを活用する方法
- UE5.5がインストールされた環境にUE5.4を追加で導入する方法
- World PartitionとWorld Compositionの違い
- オープンワールドテンプレートとは?
- ポーンをスポーンさせても視点を切り替えない方法
- キャラクター同士がすり抜けてしまう問題の解決方法
- キャラクターの外見を動的に変更
- World Partitionでインスタンスが「アンロード済み」になる問題
- データ アセットとデータ テーブルの違い
- コンポーネントイベントグラフ内で親クラスの変数にアクセスする方
- エディターのソースコードの自動保存の頻度を高める方法
- SpawnActorでSpawn Transform Rotationが反映されない理由
- ミニマップを表示しポーンの位置を反映する方法
- RInterp ToとVInterp Toの違い
- 毎秒実行するイベントの定義方法
- Niagara のエフェクトにコリジョンを持たせる方法
- 「Overlap」と「Hit」の違い
- OverlapはあるがHitがない原因
- Overlapした位置の座標を取得する方法
- ブループリントでレベル間のパラメータを受け渡す方法
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?