UnrealEngine4: レベル遷移時の保持データやりとり

15/06/2017

Programing UnrealEngine4

本記事は UnrealEngine 4.16.1 を使用

レベル遷移(マップ移動)処理は "Open Level" 関数のみで出来ます。
しかしレベルを跨ぐと保持しているデータが消えてしまいます。
調べてみるとデータ受け渡し方法は複数あったため、その方法を記載します。


目次

0.準備

事前に用意するものは
  1. 遷移するための2つのレベル
  2. 自キャラのデータを保持しておくための変数
  3. 保持している値を表示するメソッド
  4. 保持している値を増加させるメソッド

0.1 遷移するための2つのレベルを作成

プロジェクトは空でも何でも良いのですが、簡略化のため「Third Person」で新規プロジェクトを作成します。

エディタ画面が起動すると、当然サンプルのレベルが一つ用意されているので、保存されている場所を確認します(Content/ThirdPersonBP/Maps/ThirdPersonExampleMap)。

このレベルを遷移元として、同じ階層にもう一つのレベルを作成してみましょう。

File → New Level からレベルを新規作成。種類は Default で良いです。

World Settings → Game Mode → GameMode Override を ThirdPersonGameMode に変更。レベルの名前は適当に NextMap とでもつけておきます。

0.2 自キャラのデータを保持しておく変数を作成

ThirdPersonExampleMap に戻って、配置されている ThirdPersonCharacter をクリックし、Edit Blueprint 等からブループリントを開きます。

MyBlueprint → Variables の「+」をクリックして Integer 型の変数を追加、変数名は TestNum としデフォルト値はゼロとしました。

0.3 保持している値を表示するためのメソッドを作成

簡単に済ませるため値を "Print String" で表示させるようにします。

レベルのブループリントで、以下のようにチャートを作成。

これで自キャラの Test Num を常に表示してくれるようになったので、もう一方のレベル(NextMap)にも同じメソッドをコピペします。

0.4 保持している値を増加させるメソッドを作成

表示ができたので、値を増加させるメソッドを作ります。
キーボードの「N」を押すと数字が一つ加算される仕様を、自キャラに埋め込みます。

Content Browser から Content → ThirdPersonBP → Blueprints と開くと ThirdPersonCharacter があるので、ダブルクリックでブループリントを開き、以下のようにチャートを組みます。

これで準備は完了。
プレイして「N」キーを押すと、表示される数字が増えるのを確認してみましょう。

1.レベル遷移の方法

今回は特定の場所に触れるとレベル遷移するギミックを作ります。
レベル間の移動は "Open Level" 関数を利用します。

ThirdPersonExampleMap の任意の場所に、Geometry の Box を設置します(ここでは分かりやすいので、?マークが回転している位置に設置)。

Box の Details → Collision → Collision Presets を Trigger に設定。

Box を右クリックし、Add Event → OnActorBeginOverlap を選択するとブループリントが開くので、以下のチャートを組みます。

”Open Level" の Level Name に遷移先のレベル名を入力することにより、そこに遷移する仕組みです。

たったこれだけで遷移メソッドが完成しました。


さて、プレイし「N」キーで値を増やした後に NextMap へ移動するとどうなるでしょうか。
増やした値がゼロに戻ってしまったと思います。
例えば、マップ1で貯めたコインがマップ2に移るとゼロになってしまったら困るので、何とかして値も一緒に移動させたいところです。

2.値を保持したまま遷移させる方法

レベルを跨ぐ値の遷移方法を調べてみると、
  1. GameInstance を使う
  2. セーブデータを使う
これらの方法がヒット。それぞれについて見ていきましょう。

2.1 GameInstance を使う

レベル遷移が起こっても値を保持しておくための GameInstance という仕組みがあります。
一つ作ってプロジェクトに紐づけておくと、GameInstance 内の値はゲーム中保持されたままとなる便利なクラスです。

では早速 GameInstance を使っていきましょう。

新規ブループリントを作成し、カスタムクラスで GameInstance を選択し作成。名前はとりあえず MyGameInstance にしておきます。

Edit → Project Settings でウィンドウを開き、Map & Modes → Game Instance → Game Instance Class に作成した MyGameInstance を指定。

これで自分の GameInstance が使えるようになりました。

では、GameInstance に数を記憶させる変数を作りましょう。

MyGameInstance をダブルクリックし、ブループリントを開きます。

MyBlueprints → Variables の「+」をクリックし、Integer型でデフォルトの数値がゼロの変数を作成。ここでは変数名を InstanceNum としました。

この InstanceNum の数を増加させ、表示させる必要があるので、項目0.3、0.4で作ったメソッドを以下のように改良しました。

どちらも MyGameInstance の InstanceNum を呼び出すため、"Get Game Instance" でMyGameInstance をキャストしています。

「N」キーを押すと MyGameInstance の InstanceNum の数が1追加されるようにしたのがこちら。

InstanceNum の値を表示させるようにしたのがこちら。2つのレベル双方にこのチャートを組み込みます(関数化すれば楽だったが今回はせず)。

プレイしてみると、しっかり遷移後も数値が残っているのが分かるでしょう。

2.2 セーブデータ を使う

当然ながら、ゲーム内のデータをセーブ&ロードする機能がついています。
それを使って遷移時に値を受け渡せば、GameInstance と同様のことができます。

セーブ機能を使うため、新規ブループリントを作成、カスタムクラスで SaveGame を選択し作成します。名前はとりあえず MySaveGame にしておきましょう。
これでセーブ機能を使うことができるようになりました。

では、SaveGame に数を記憶させる変数を作りましょう。

MySaveGame をダブルクリックし、ブループリントを開きます。

MyBlueprints → Variables の「+」をクリックし、Integer型でデフォルトの数値がゼロの変数を作成。ここでは変数名を SaveNum としました。

また、編集可能にするため Instance Editable にチェックを入れます。

普段は自キャラの TestNum の値を増加させるため、自キャラの値増加処理、表示処理は項目0.3、0.4のまま(2.1の改良版ではなく初期のもの)にしておきます。

遷移時のみ一時的に SaveNum に値を移し、遷移後の自キャラにその値を移しかえる処理を作っていきます。

まず、遷移のトリガーに引っかかった際にセーブする処理が以下。項目1で作成したレベルブループリントの遷移処理を改良したものです。

上の処理を順に紐解くと、
  1. "Create Save Game Object" でセーブ用オブジェクトを作成。Save Game Class を先ほど作った MySaveGame に指定すると、キャストと同等の効果になる。
  2. "Create Save Game Object" の Return Value からピンを伸ばし、値を入れる Save Num を set で呼び出す。
  3. 当然保存する値を自キャラから持ってこなくてはならないため、"Get Player Pawn" 以下の経路を敷く。
  4. "Set Save Num" の次に "Save Game to Slot" を実行しているが、ここでデータがローカルに保存される。保存場所はデフォルトで〈プロジェクトフォルダ/Saved/SaveGames/***.sav〉となり、*** には Slot Name で指定した名前が入る。
  5. 次のレベルへ遷移
となります。

次にデータをロードする処理に入ります。
この処理はレベルが開いた際にデータを読み込むので、レベルブループリントの "Event BeginPlay" から繋ぎます。

こちらも順に紐解いていきましょう。
  1. "Load Game from Slot" で保存されているデータをロードする。スロットの名前を指定するのを忘れないこと。
  2. 中身の変数を扱うため、MySaveGame としてキャストし、SaveNum を取り出す。
  3. 自キャラに値をセットするため、こちらも "Get Player Pawn" からキャストし、セットを実行。
ちなみにこの "Load Game from Slot" で指定したスロット名が無い(セーブファイルが無い)場合は、キャストが失敗し Cast Failed ピンに実行が流れます。

プレイしてみると、項目2.1と同様の結果になるはずです。

3.まとめ

レベル遷移時のデータ受け渡しは、GameInstance とセーブデータを使う方法で実現できることが分かりました。

単純に遷移時の使い勝手は GameInstance のほうが良さそうですが、データ数との兼ね合いもあり、状況次第といったところでしょうか。


【参考リンク】

Major Contents

ブログ アーカイブ

Contact us

名前

メール *

メッセージ *

QooQ