関連ブログ
- [UE4][UE5]開発環境の容量を少しでも減らす 2024.08.14UE
- [UE5] PushModel型のReplicationを使い、ネットワーク最適化を図る 2024.05.29UE
- [UE5]マテリアルでメッシュをスケールする方法 2024.01.17UE
CATEGORY
2016.12.09UE4UE/ Blueprint
UE4にて皆さんは状況に応じてサブレベルを切り替えるような処理を行っている場合もあるかと思います。
今日はそのサブレベルの読み込みに関して、知らないと思わぬバグを招いてしまう内容をご紹介したいと思います。
例えば、あるゲーム内で時間経過によって状況が変化するステージがあるとします。ゲーム上で昼にしか起きないイベント、夜にしか出現しない敵などです。
このように昼間、夜間によって全くイベントの内容が異なる場合、管理のしやすさから夜用イベントのサブレベルと昼用イベントのサブレベルというように、一つのステージにイベント起動用のサブレベルを複数に分ける場合があると思います。
そして、イベント起動はどれもトリガーボリュームなどのイベント用アクターのコリジョンで判定するとします。
ここまでは、とくに問題ないはずです。あとはゲーム中に昼になったら夜用のサブレベルを破棄し、昼用のサブレベルを読み込む。そして夜がきたら昼用のサブレベルを破棄し、夜用のサブレベルを読み込めば、それぞれの時間帯に応じたイベントが起動できるようになるはずです。
しかし、このような作りになっていた場合、コリジョンの検知タイミングをよく把握していないと、次のような問題が発生します。
昼間に夜用のイベントが発生する場所にいた場合、そのまま夜になったとしても、夜のイベントがきちんと発生しないのです。
実際に検証してみましょう。
まずサブレベルに昼用イベントの「Event_Day.umap」、夜用イベントの「Event_Night.umap」を追加します。
次に各レベルにそれぞれのイベント起動用にトリガーボックスのアクターを配置します。
今回は単純に、レベルブループリントでトリガー内に入った時と出た時にデバッグ表示をするようにします。
あとは任意のタイミングでサブレベルを切り替れるようにパーシスタントのレベルに処理を書きます。
そして、実際に起動して挙動を確かめてみると、トリガーがある場所にでサブレベルを切り替えると、トリガー内にも関わらずイベントは発生しない事が確認できます。
一度トリガーの外に出て再度入ると、きちんとBeginOverlapのイベントが起動することがわかります。
さて、ではサブレベルを切り替えた直後に、トリガー内にいるならBeginOverlapを走らせたい場合はどうすればいいのでしょうか。
方法はいくつかあります。
一つ目は、トリガー側もしくはプレイヤー側(判定の対象となる側)のどちらかのコリジョンを一度無効にして、再度有効にすることです。
BeginOverlapイベントは、コリジョンの中に入った瞬間以外にも、コリジョンが有効になった瞬間にその中に既に入っている場合も呼ばれるからです。
もしサブレベルの切り替えにプレイヤー側のコリジョンを無効にする場合は、専用のコリジョンを用意し、それの有効無効を切り替えることをお勧めします。何の対策もしないままコリジョンを無効にするとそのキャラクターは地面をすり抜けてしまいますからね。
また、トリガー側のコリジョンを予め無効にしておき、BeginPlayなどの任意のタイミングでコリジョンを有効にする方法も効果的ではあります。ですが、各トリガーのブループリントごとに設定しておく必要があるなど、ワークフロー的にデメリットがありそうです。トリガー用のブリープリントが1種類か、もしくは基底クラスのブループリントを用意しておくなどの対策はありますが…
二つ目の解決策は、トリガー用のブループリント内のBeginPlayなど、任意のタイミングでOverlapping判定を使って自力で今トリガーの中に入っているか判定することです。
イベントが飛んでこないなら自分で調べようというやや強引な手法になります。
他にもGetOverlappingActorsというノードを使えば、現在トリガー内に入っている全てのアクターをクラス指定で複数取得することもできるので、こちらも有効です。
そして二つ目ですが、実はこの記事を書くにあたって色々と検証していた際に偶然発見した機能です。
なんとUE4.13から指定できるようになった、アクターの詳細の「GenerateOVerlapEventsDuringLevelStreaming」をTrueにしておくことでこの問題をずばり解決できます。下手に対策を打つよりは素直にこちらの設定を有効にしておいた方が安全そうです。(むしろこのフラグで解決できる単純な話でした…)
コリジョン判定のタイミングは、ゲームを作る上でとても重要なのは皆さんも知ってのとおりです。
アクターがどの状態になっていたらBeginOverlapやEndOverlapが走るのか、きちんと把握してコリジョン周りのバグを無くしていきましょう。