【開発環境】
- Windows 11
- UE5.8 カスタムエンジン
お世話になっております。
表題の通り、MassAIを負荷削減のために一時的に止める方法についての質問になります。
当プロジェクトでは、群衆制御にMassAIを利用しております。
基本的にはインゲームマップにいる最中はずっと稼働しているのですが、インゲーム中におこるイベント的な期間(数分~十数分)だけ、ゲームスレッドの負荷削減のためにMassAIを一時的に止めたいと考えております。(イベントが終われば再稼働させたい。)
UMassSimulationSubsystemを見ると、それらしい関数が見当たりました。
- PauseSimulation / ResumeSimulation:public関数
- StopSimulation / StartSimulation:protected関数で、コンソール変数のmass.SimulationTickingEnabled 経由で実行。
それぞれ試してみたところ、いずれも挙動と負荷削減ともにそれらしい効果が得られました。
ただ、負荷の面で言うと、[Mass Total Frame Time]の定常コストが、Stop/Startのほうは0になったのに対し、Pause/Resumeのほうはパッケージ計測で数百μsだけ残る([Mass Phase Tick]がかかっている)、という結果になりました。
Pause/Resumeのほうでも十分な効果が得られてはいますが、最適化という意味では0にできるならしたいとも思っています。Stop/Startのほうはprotected関数ですが、今回のように一時的に止める(その後、再稼働させる)という用途で使う上での不都合などはございますでしょうか?
ご教示よろしくお願いします。
[Attachment Removed]
お世話になっております。
用途だけで言えば、Pause/Resumeをご利用頂くことの方が合っており、また重い処理の殆どが停止しているため効果はあります。
・Stop / Start を一時停止に使う場合の副作用
再開が「初めて開始した」扱いになり、スポーン(通知)が二重に走り得る可能性があります。例えば Stop で停止中にWPのストリーミングによってSpawnerが生成された場合、OnSimulationStarted をブロードキャスト配信しますが、イベントが完了して Start を実施した場合、Stop中に生成されたSpawnerに対して再度OnSimulationStarted が通知されることが想定されます。
また、PhaseManager が EntityManager 参照を Reset し、OnNewArchetype を外すため、Stop で停止中に新しい種類のエンティティが増えると、再開後のプロセッサ依存グラフが古いままになることがあります。いずれも、イベント中に 誰もSpawn が発生しなければ起きないケースのため、これらが考慮される場合は利用できる可能性はあります。
・フェーズ Tick まで 0 にしたい場合
Pause 中も、エンジンは毎フレーム Massに6回Tick経由でフェーズの通知の呼びだしを行います。このフェーズ毎の通知がある/なしが、Pause/Stopの違いの部分です。中でプロセッサの実処理は走りませんが、呼び出し・計測・開始/終了の通知は残ります。それが [Mass Phase Tick] の数百μsです。Stop が0になるのは、この呼び出し自体を切るからです。そのため、Pause でこの呼び出しを切る場合は、Stop/Start は使わずTick 関数だけ切る方が副作用が少ないです。エンジンに手を入れるなら、UMassSimulationSubsystem にこの"Tick だけ止める"処理を足す方が、Stopをpublicにするよりベターかもしれません。
FMassProcessingPhaseManager& PhaseManager = MassSim->GetMutablePhaseManager();
for (uint8 i = 0; i < static_cast<uint8>(EMassProcessingPhase::MAX); ++i)
{
PhaseManager.GetProcessingPhaseTickFunction(static_cast<EMassProcessingPhase>(i))
.SetTickFunctionEnable(bEnable);
}
[Attachment Removed]
ご回答ありがとうございます!
では、安全優先で、ひとまずはPause/Resumeのほうを採用したいと思います。
また、フェーズ Tickをなくす対応も、必要に迫られたときはご教示いただいた方法で対応しようと思います。
[Attachment Removed]