関連ブログ
- [UE4][UE5]開発環境の容量を少しでも減らす 2024.08.14UE
- [UE5] PushModel型のReplicationを使い、ネットワーク最適化を図る 2024.05.29UE
- [UE5]マテリアルでメッシュをスケールする方法 2024.01.17UE
CATEGORY
2016.02.10UE4UE/ Streaming
改訂バージョン: Unreal Engine 4.19 |
今回はレベルの読み込み回りについてのお話をしたいと思います。
話を進める上で、少し内容が混乱してしまうため、便宜的に単語を定義付けたいと思います。
レベル | UE4で拡張子がumapになっているアセットのこと |
マップ | パーシスタントレベルと複数のサブレベルで構成されるレベルのこと |
UE4にはレベルを複数に分ける機能があります。
もちろんレベルを分けずに、親レベルであるパーシスタントレベルに全てのアクターを配置することも可能ですが、レベル分けを活用することで、よりゲームを作りやすくすることが可能です。
レベルを分ける事によるメリットは様々ですが、敢えて挙げるとすれば以下のような内容ではないでしょうか。
さて、実際にレベル分けを行った場合、次に必要になってくるのはレベルの読み込みタイミングの管理です。
そこでレベルの追加方法を確認しながら解説していきたいと思います。
まず、レベルウィンドウのレベルメニューから「新規作成」を選択肢し、新しいレベルを追加します。
この時追加した新規レベルは、そのまま実行しても読み込まれません。
これはレベルのデフォルトのストリーミング方法がブループリント制御になっているからです。
デフォルトのストリーミング方法
ブループリント | ブループリントによって制御します |
常にロード済み | パーシスタントレベルを読み込んだ際、自動的に一緒に読み込まれます 読み込み方法は同期読み込みで、このレベルの読み込み及び表示が完了するまで、次のサブレベルの読み込みは発生しません |
今回はブループリントによる制御で話を進めます。では、ブループリント制御にしたい場合はどんな時でしょうか。
レベルの使用意図に合わせてこれらを使い分けます。
ちなみに1のパーシスタントレベルが読み込まれた際に自動で非同期読み込みを行いたい場合は、レベル詳細から設定できます。
変更したいレベルを選択し、レベルの詳細アイコンを押すと、そのレベルの詳細ウィンドウが開きます。
Initially Loaded | チェックマークを入れると自動で非同期読み込みを行います |
Initially Visible | チェックマークを入れると読み込み後に表示まで一緒に行います |
今回は任意のタイミングでのレベルの管理を行いたいので、設定はそのままにしておきます。
さて、では任意のタイミングでレベルを読み込む手段ですが、これはUE4だと2つ用意されています。
まず1のLevel Streaming Volumeを使用する場合です。
このボリュームは少々特殊で、パーシスタントレベルに置くことでしか効果を発揮しません。
レベルの読み込みを管理するボリュームなので、必ず読み込まれるパーシスタントレベルに置くのは当然ですし、そもそも別のレベルに配置して設定しようとすると警告が出ます。
次に各サブレベルのレベル詳細で、対象となる配置したLevel Streaming Volumeを選択して紐付けます。
これでボリューム内にプレイヤーが侵入した際に、紐付けたレベルが読み込まれるようになります。
読み込み方法についてはボリューム側で設定できます。
Streaming Usage
SVB Loading | 非同期読み込みのみ |
SVB Loading and Visibility | 非同期読み込み後レベル表示(デフォルト設定) |
SVB Visibility Blocking on Load | 同期読み込み後、表示完了まで待つ |
SVB Blocking on Load | 同期読み込みのみ行う |
SVB Loading Not Visible | 非同期読み込み後に非表示状態を保つ。Load Stream LevelやShould Be Visbleでも表示状態にならないので注意 |
次に2のブループリント内でLoad Stream Levelノードを使用する場合です。
この関数は処理待ちが発生するLatentノードなので、関数では使えません。使用する場合はイベント内やマクロで使用しましょう。
Level Name | レベル名 |
Make Visible After Load | 読み込み後に表示を行うかどうか |
Should Block on Load | 同期読み込みを行うかどうか |
さて、これでレベルの読み込み関連は一通り紹介しましたが、もう少し踏み込んでみましょう。
それはレベルの表示タイミングです。
レベルには、ロード済の状態でも表示状態と非表示状態の2種類の状態が存在します。
普段エディタで作業している時に、レベル単位で表示非表示を切り替える場合もあるかと思いますが、それと同じようにゲーム中にレベル単位で表示の切り替えが可能です。
ちなみにレベルウィンドウの各レベルの左横にある目マークのアイコンでどちらの状態か確認することができます。
ではレベルをロードするタイミングと表示するタイミングで分ける必要があるでしょうか?
メリットはあります。例えばメモリには余裕があるけど描画速度がキツイ…といった場合に有効です。
具体的にはある程度広いマップを使ったゲームなどが該当すると思います。
そこで背景レベルなどをいくつかに分割し、表示が必要でない箇所は非表示状態にしておけば、必要な時に素早く表示状態にできるというわけです。
似たような機能としてUE4にはWorldCompositionというオープンワールド用の機能が存在しますが、それを使わない場合はこういったテクニックを使うという選択肢も視野に入れてみてはどうでしょう。
話を戻しましょう。実際の実装方法としましては、二通り存在します
さて、このように表示タイミングを分けた場合、どうしても表示完了のタイミングを知りたいという状況があるかと思います。なぜならUE4のレベルの表示は一瞬で切り替わるものではなく、次第に表示されるような仕様になっているからです。つまり表示完了待ちというタイミング発生するわけです。
そこで指定レベルの表示が完了したかを調べる方法があります。
Get Streaming LevelからIs Level Visibleで判定を取る事が可能です。
これを実際に使える形としてマクロ化したものがこちらになります。
そして実際のマクロの使用例がこちらになります。引数を配列にすることで複数のレベルに対して同時に判定を行っていますが、その必要が無い場合はもっと中身は簡潔なもになるかと思います。
また、コンソールコマンドの「stat LEVELS」でもレベルの読み込み状況がリアルタイムに確認できるため、デバッグ時はこちらを積極的に活用していきましょう
このようにレベルの読み込みや表示タイミングを状況に合わせて自在に操れるようになれば、レベル管理も様々な状況で対応できるのではないでしょうか
Level Streaming Volumeですが、ボリュームの設定方法としては他と違って少し特殊です。
レベル詳細の方で各ボリュームと紐付けるのはワークフロー的にちょっと…と思う方もいるかもしれません。
そんな時はボリュームクラスを基底クラスにブループリントを作成できるようにエンジン側を弄ることで、解消できるかと思います。
ブループリントでボリューム内に入った時に対象レベルを読み込み(或いは表示)、出た時に破棄(或いは非表示)といった処理にすれば、他のボリューム配置と同様のワークフローで完結します。