タイトル: Blueprintでプロジェクト全体で共有できるStatic定数の定義方法
SEOタイトル: UE5ブループリントでプロジェクト共有の定数を定義する方法|Data Asset・Data Table活用
Unreal Engine 5(UE5)のブループリント(BP)でプロジェクト全体から参照できる定数を定義したい場合は、値を保持した「Data Asset」または「Data Table」を作成し、各ブループリントからその資産を取得して値を読み出すのが基本的なアプローチになります。BPにはC++のような言語仕様としての static 定数は存在しないため、「定数を持った専用のアセット(データ資産)を1つ用意し、それを唯一の参照元にする」という設計で代替するのが定石です。本記事では、ゲームバランス値(攻撃力・所持金上限・各種倍率など)のような値をプロジェクト全体で一元管理する代表的な方法を、用途別に整理して解説します。
| この記事の要点 |
|---|
|
なぜBPには「static定数」が無いのか
C++では static constexpr や static const を使って、インスタンスを生成せずクラス単位で共有される不変の値を定義できます。一方、UE5のブループリントは、こうした「クラスに紐づく静的メンバー」や「コンパイル時定数」を直接宣言する言語機能を備えていません。ブループリントの変数は基本的に「そのブループリントのインスタンス」に属する値であり、グローバルに1つだけ存在して書き換え不可、という性質を素直には表現できません。
そのため、BPで「プロジェクト全体で共有する定数」を実現するには、値そのものではなく「値を保持したアセットや常駐オブジェクトを、唯一の参照元として用意する」という発想に切り替えます。以下では用途別に4つの方法を紹介します。なお、各UIの名称や操作手順はエンジンのバージョンによって細部が異なる場合があるため、最終的には利用中のバージョンの公式ドキュメントを確認することをおすすめします。
方法①:Data Asset(Primary Data Asset)に定数を持たせる
もっとも扱いやすく、定数の一元管理に向いているのが Data Asset です。とくに、Asset Managerと連携できる Primary Data Asset(基底クラス UPrimaryDataAsset)を親に選ぶと、複数のデータ資産をまとめて管理・ロードしやすくなります。エディタ上で型付きの値(整数・浮動小数・文字列・他アセットへの参照など)を編集できるため、ゲームバランス値の置き場として見通しが良いのが特徴です。
大まかな流れ:
- 定数の入れ物となるブループリントクラスを、親クラスに「Primary Data Asset(または Data Asset)」を選んで作成する。
- そのクラスに、攻撃力・所持金上限・倍率などの変数を追加する(必要なら構造体や配列としてまとめる)。
- Content Browserで、そのクラスのインスタンスとなるData Assetアセットを作成し、エディタ上で実際の値を入力する。
- 各ブループリントから、このData Assetへの参照を持たせて値を読み出す(参照の渡し方は後述の「落とし穴」を参照)。
メリットは、値の型が明確で、エディタ上で安全に編集でき、変更がアセット単位で完結する点です。デメリットとしては、参照(アセットをどこから・どう取得するか)の設計を最初に決めておく必要がある点が挙げられます。
方法②:Game Instance の変数に持たせる
Game Instance は、ゲーム起動からセッション中ずっと(レベル遷移をまたいでも)破棄されずに保持される常駐オブジェクトです。ここに変数を置けば、どのブループリントからでも Get Game Instance 経由でアクセスでき、「セッション中に共有したい値」の置き場として機能します。
大まかな流れ:
- Game Instanceを継承したブループリントクラスを作成し、プロジェクト設定でそのクラスを使うよう指定する。
- 共有したい変数を追加する。
- 各所で
Get Game Instanceを取得し、対象クラスにキャストして変数を読み出す。
ただし注意したいのは、Game Instanceの変数は実行中に書き換え可能であり、本来の意味での「不変の定数」ではないという点です。むしろGame Instanceは「現在のプレイ状況(難易度設定、選択キャラクター、進行状況など)」のような可変のセッション状態を持たせる用途に向いています。固定値の置き場としても使えますが、「誰かが途中で値を変えてしまう」リスクがあることは理解しておきましょう。
方法③:Enum・構造体・Data Table・Curve Table を使う
「単一の値」ではなく「種類の集合」や「表形式のデータ」を扱いたい場合は、次の資産が有効です。
- 列挙型(Enum):状態やカテゴリなど、決まった選択肢の集合を表す。BP全体で共通の「種類」を定義でき、分岐の可読性が上がる。
- 構造体(Struct):関連する複数の値を1つにまとめた型。Data AssetやData Tableの「1行ぶんの形」を定義するのに使う。
- Data Table:構造体を行の型(Row Struct)として、表形式で複数行のデータを管理する資産。スプレッドシート的に大量のパラメータを並べられ、CSV等からの取り込みにも対応するため、アイテム一覧や敵パラメータ表のように行数の多いバランス値を扱うのに向く。
- Curve Table / Curve:レベルや時間に応じて連続的に変化する値(例:レベルごとの必要経験値や攻撃力スケーリング)をカーブとして定義できる。「レベルNのときの値」のような入力に対して値が変わる定数表を扱える。
これらは方法①のData Assetと組み合わせて使うこともでき、たとえば「Data Assetの中からData TableやCurveを参照する」といった構成も一般的です。
方法④:C++ の static 定数・UENUM をブループリントへ公開する
プロジェクトにC++を導入している場合は、C++側で static constexpr などの真に不変な定数を定義し、それをブループリントから読めるように公開する方法もあります。たとえば、定数を返す UFUNCTION(純粋関数)を用意してBPから呼び出す、あるいは UENUM で定義した列挙型をBPと共有する、といった形です。
この方法は、値がコンパイル時に固定され、実行中に書き換えられる余地が無いという点で「定数」の意味に最も忠実です。一方で、値の変更にC++のビルドが必要になり、デザイナーがエディタ上で手軽に調整するワークフローには向きません。「絶対に変えてはいけない内部定数」はC++側、「調整しながら詰めていくバランス値」はData Asset/Data Table側、と棲み分けると扱いやすくなります。
方法の比較
| 方法 | 共有範囲 | 編集しやすさ | 不変性 | 向いている用途 |
|---|---|---|---|---|
| Data Asset | プロジェクト全体 | 高(エディタで型付き編集) | 運用次第(書き換えは可能) | バランス値の一元管理全般 |
| Data Table | プロジェクト全体 | 高(表形式・CSV取込) | 運用次第 | 行数の多い一覧・パラメータ表 |
| Curve Table / Curve | プロジェクト全体 | 中(カーブ編集) | 運用次第 | レベル等で変化する値 |
| Game Instance 変数 | セッション中 | 中(実行時に変化しうる) | 低(途中で書換可能) | 可変のセッション状態 |
| C++ static / UENUM | プロジェクト全体 | 低(ビルドが必要) | 高(コンパイル時固定) | 変更しない内部定数・列挙 |
おすすめの選び方
多くのプロジェクトでは、まず Data Asset または Data Table を起点に考えるのがおすすめです。理由は、型付きの値をエディタ上で安全に編集でき、プログラマー以外のメンバーでもバランス調整に参加しやすく、参照元を1つに集約しやすいためです。
- 個別の設定値や、関連する値のまとまりを管理したい → Data Asset
- アイテム表・敵ステータス表のように行数が多い → Data Table
- レベルや時間で連続的に変化する値 → Curve / Curve Table
- セッション中に変化する状態(進行度・選択中の難易度など)→ Game Instance(定数ではなく状態として)
- 絶対に変えない内部定数・列挙を厳密に固定したい → C++ の static / UENUM
落とし穴と注意点
| 注意点 | 内容 |
|---|---|
| Game Instance を「定数」と誤解しない | Game Instanceの変数は実行中に書き換え可能で、不変が保証されません。「定数のつもり」で置いた値が、別のロジックから変更されてバグの原因になることがあります。固定値を厳密に守りたいなら、編集箇所を限定するか、C++のstaticを検討します。 |
| 値のハードコードが各所に散在する | 同じ数値を複数のブループリントに直接書き込むと、調整のたびに全箇所を直す必要があり、修正漏れが起きます。定数は必ず1つのデータ資産に集約し、各所はそこを参照する形にします。 |
| 参照(取得経路)の持ち方が曖昧 | 「Data Assetをどこから取得するか」を決めずに各所で個別にロードすると、参照が分散して保守しづらくなります。Asset Managerや専用のサブシステム経由など、取得経路を1本化しておくと管理が楽になります。 |
| 参照アセットのロードタイミング | 他アセットへの参照を含むData Assetは、ロードのタイミングやハード参照/ソフト参照の扱いによって、メモリ使用や読み込み挙動が変わります。大量のアセットを扱う場合はAsset Managerの仕組みを理解しておくと安全です。 |
よくある質問(FAQ)
Q. 結局、最初はどれを使えばいいですか?
A. プログラマー以外も値を調整するチームなら、まず Data Asset(または行数が多ければ Data Table)から始めるのがおすすめです。エディタ上で型付きの値を安全に編集でき、参照元を1つに集約しやすいためです。
Q. Game Instance に定数を置くのは間違いですか?
A. 間違いではありませんが、Game Instanceの変数は実行中に書き換え可能で「不変」が保証されません。固定値の置き場としても使えますが、本来は難易度設定や進行状況のような可変のセッション状態に向いています。厳密に不変にしたい値は、編集箇所を限定するかC++のstaticを検討してください。
Q. C++を使わずにBPだけで「本当の定数(書き換え不可)」は作れますか?
A. BPの言語仕様としての static 定数はありません。Data Assetやマップ上に配置しないData-Only Blueprintを参照専用として運用すれば実質的に「変更しない値」として扱えますが、書き換え不可をエンジンに強制させたい場合はC++の static 定数を公開する方法が確実です。
UE5のブループリントでプロジェクト全体の定数を扱うときは、「言語的なstaticを再現する」のではなく、「定数を保持したアセットを唯一の参照元として設計する」という視点で組み立てると、保守しやすくバランス調整も進めやすい構成になります。各機能の詳細な仕様や手順は、利用中のエンジンバージョンの公式ドキュメントもあわせて確認してください。