Unreal Engine 5(以下、UE5)では、異なるレベル間でデータを共有・受け渡す場面が頻繁に発生します。 たとえば、タイトル画面で選択したキャラクターや設定をゲーム本編のレベルへ渡したい場合などが典型的な例です。 本記事では、ブループリント(Blueprint)を使って、レベル間でデータをやりとりする方法を、具体的かつ丁寧に解説していきます。

方法1:GameInstanceを活用する

レベルをまたいでデータを保持するには、GameInstanceという仕組みを使うのが最も一般的でおすすめです。 これはエンジンがアプリケーション起動から終了まで生存する特別なクラスで、レベルを切り替えてもリセットされません。

GameModePlayerControllerも似たような用途に思えますが、これらはレベルを移動するときに破棄・再生成されるため、永続的なデータ保持には向いていません。

ステップ1:GameInstanceを継承したクラスを作成

まずは、BlueprintベースのGameInstanceクラスを作成します。

1. コンテンツブラウザを右クリックし、「Blueprint Class」を選択
2. 「All Classes」を表示し、GameInstanceを検索して選択
3. 任意の名前(例:MyGameInstance)を付けて保存

このクラスに、渡したいパラメータ(変数)を追加します。たとえば、選択キャラの名前を渡したい場合は、String型の変数を追加します。

ステップ2:プロジェクト設定で使用するGameInstanceを指定

作成したGameInstanceを使うためには、プロジェクト設定で明示的に指定する必要があります。

1. メニューバーから「Edit(編集)」→「Project Settings」を選択
2. 左側のメニューから「Maps & Modes」を開く
3. 「Game Instance Class」の項目で、先ほど作成した「MyGameInstance」を選択

ステップ3:レベルAでデータをセット

たとえばタイトル画面でプレイヤーがキャラを選んだ後、その名前をGameInstanceに格納するコードは以下のようになります。

1. ブループリント内で「Get Game Instance」ノードを追加
2. 「Cast To MyGameInstance」ノードを使って、作成したGameInstanceクラスにキャスト
3. キャスト後の出力ピンから、作成した変数(例:SelectedCharacterName)にSetノードで値を代入

ステップ4:レベルBでデータを取得

データを取得したいレベルでは、以下のようにします。

1. イベントグラフの「BeginPlay」などで処理を開始
2. 「Get Game Instance」→「Cast To MyGameInstance」
3. キャスト後、変数をGetノードで取得し、必要に応じてUIやゲームロジックに渡します

補足:データ型と初期化タイミングに注意

GameInstanceに保存する変数のデータ型は、レベル間で共有する内容に応じて決めましょう。 単純な数値や文字列だけでなく、構造体や配列、参照型(オブジェクト)も格納可能です。 ただし、オブジェクト参照はレベルが変わると無効になる場合があるため注意が必要です。

また、BeginPlayの実行タイミングなどにより、GameInstanceの変数が未設定のまま参照されることがあるため、Nullチェックを入れておくと安全です。

 

方法2:SaveGameクラスを使ってデータを保存・読込する

もう一つの定番手法は、SaveGameクラスを使用する方法です。 これは主にゲームのセーブ・ロード用に設計されていますが、実は一時的なデータ受け渡しにも活用できます。

手順としては、まずSaveGameを継承したBPを作成し、そこに変数を追加します。 データを保存したいタイミングでCreate SaveGame Objectノードを使ってインスタンスを作成し、変数に値を代入後、Save Game to Slotします。 次のレベルでは、Load Game from Slotで読み込み、データを取り出します。

この方法は、レベル移動だけでなく、ゲームを終了しても保持したい情報にも向いています。 ただし、毎回ディスクにアクセスするため、頻繁な使用や高速性を求める用途には不向きです。

方法3:Level間の遷移時にパラメータをURL経由で渡す

UE5では、Open Levelノードを使ってレベル遷移する際に、URLにパラメータを埋め込むことも可能です。 これはコンソールゲームというよりは、オンラインゲームやエディタスクリプトで便利な機能ですが、場合によっては応用できます。

たとえば以下のように記述します:
Open Level (LevelName?MyParam=123)
遷移先のレベルでは、Get Optionsノードを使用してそのパラメータを取得し、Parse Optionなどで値を抜き出します。

この方法は低レベルな仕組みで柔軟性がありますが、文字列しか扱えないため、複雑なデータ構造には不向きです。 また、あまり一般的な手法ではないため、プロジェクトチーム全体で仕様を把握している場合に限定して使うと良いでしょう。

方法4:Subsystemを使った高レベルな管理

UE5では、Subsystemという新しい設計パターンが導入されており、これもレベルをまたいだデータ管理に使うことができます。 特にGameInstance Subsystemを使うと、GameInstanceと同様に永続的なデータを扱えます。

Blueprintから作成する場合は、「Blueprint Class」→「All Classes」→「GameInstanceSubsystem」を継承したクラスを作成し、そこに変数や関数を定義します。 その後、Get Game Instance Subsystemノードを使ってどのレベルからでもアクセス可能です。

Subsystemはより柔軟かつモジュール的に設計できるため、中〜大規模プロジェクトで複数の機能を分離管理したい場合におすすめです。 ただし、Subsystemのライフサイクルや初期化順序を正しく理解して使う必要があります。

どの方法を選ぶべき?

簡単に比較すると以下のようになります:

  • GameInstance:最もシンプルで実用的。レベル間の一時的データ共有に最適
  • SaveGame:データ永続化が必要な場合に便利
  • URLパラメータ:軽量な値を一時的に渡すのに適しているが用途は限定的
  • Subsystem:設計の自由度が高く、大規模構成に向いている

開発するゲームの規模や目的によって最適な方法は異なります。複数の方法を併用するのも一般的です。