関連ブログ
- [UE4][UE5]開発環境の容量を少しでも減らす 2024.08.14UE
- [UE5] PushModel型のReplicationを使い、ネットワーク最適化を図る 2024.05.29UE
- [UE5]マテリアルでメッシュをスケールする方法 2024.01.17UE
CATEGORY
2020.04.29UE4
執筆バージョン: Unreal Engine 4.24 |
キャラクター同士の衝突回避を実現するためにUnrealEngineではCrowdManager(※1)とAvoidanceManagerというものがあります。
プロジェクト設定からも確認できるCrowdManagerとは違い,エディター上ではどこらかも存在を確認するこができないAvoidanceManager…
今回はそんな自分で探さない限り知り得ないであろうAvoidanceManagerについて紹介したいと思います。
AvoidanceManagerは衝突回避アルゴリズムであるRVO(Reciprocal Velocity Obstacles)(※2)をUEで使用するためのクラスで
以下の2種類のComponent内で使用されています
2つのComponentの基本的な使用方法、処理の流れはだいたい同じなため以降はCharacterMovementComponentでの使用を想定しての説明になります。
↓はNavMeshギリギリの位置にある目標ポイントに向かうときにグレイマンが常にグリーンマンの回避方向に妨害し続けた結果NavMesh外に移動してしまったグリーンマン…
その後、彼が動くことはありませんでした…
使用するための手順は非常にシンプルで
のいずれかで使用可能です。
次にブループリント上で公開されてる変数まとめました。(それとよくわからなかった変数の日本語訳を画像で…)
変数名 | 説明 |
bUseRVOAvoidance | RVOを使用した回避処理を動作させる(サーバー上でのみ動作)
クライアント環境では強制的にComponentの登録処理時、Falseに変更される |
AvoidanceConsiderationRadius | 回避処理をしだす範囲を指定します。
AvoidanceManagerではIRVOAvoidanceInterfaceのGetRVOAvoidanceOrigin(※2)から位置を取得しそこからの距離(高さは無視された2D距離)に回避対象者がいれば回避処理が継続されます。 |
AvoidanceWeight | 回避時の重み付け。0.0以上1.0未満を指定する(1以上を指定すると回避処理されなくなるため注意) |
AvoidanceUID | RVO機能を有効にしたMovementComponentを識別するためのユニークなID。
AvoidanceManagerに登録される際にIDがセットされます。 (登録されたとき1からではなく0から使用されるため最初のComponentのみ登録されてたかの確認がとれないので注意) |
AvoidanceGroup | 自身が属する回避グループ。 |
GroupsToAvoid | 回避動作をするべきグループ。デフォルトですべてのグループにチェックされてます。
チェックを外すことで回避動作をしなくすることもできますが次の項目で設定するほうが わかりやすいかと思います。 |
GroupsToIgnore | 回避動作を無視するグループ。ここにチェックしたグループが回避動作の範囲内に来ても何もしなくなります。 |
コンソールコマンドとして使用できるものは2種類あります。
使用時の注意点としてRVO機能はServer上でのみ処理されるためDebug表示もServerでのみ確認可能になっています
AvoidanceSystemToggle | Avoidanceのシステムをオンオフする |
AvoidanceDisplayAll | Avoidanceのデバック表示
↑のような感じでAvoidanceManagerに登録される対象者に青い線が表示され実際回避処理がされる間は 赤い線に変わり足元に回避した方向が表示されます。 |
1 2 |
[/Script/Engine.AvoidanceManager] DeltaTimeToPredict=0.5 |
デフォルト値 | 説明 | |
DefaultTimeToLive | 1.5 | RVO機能をオフにしてからAvoidanceManager内で完全に使用されなくなるまでの時間の猶予 |
LockTimeAfterAvoid | 0.2 | 回避処理がされVelocityが設定された後、再度計算し直されるまでの時間
(UCharacterMovementComponentではSetAvoidanceVelocityLockで設定し時間が経過するまで同じVelocityで動作し続けます) |
LockTimeAfterClean | 0.001 | 回避処理されなかったときの再度計算し直されるまでの時間。基本は毎フレームになる時間を指定。
またキャラクター同時が接触した場合などもこれが指定されすぐ再計算されるようにしてる模様 |
DeltaTimeToPredict | 0.5 | 衝突回避をする速度を求めるための予測時間 |
ArtificialRadiusExpansion | 1.5 | オブジェクトの半径に掛けられる係数(CharacterならGetScaledCapsuleRadius *ArtificialRadiusExpansionが実際計算で使用される半径のサイズ) |
HeightCheckMargin | 10.0 | 回避対象オブジェクトとの許容可能な高さ
対象オブジェクトとのZ値の差分が「対象オブジェクトの高さ+自分の高さ+HeightCheckMargin」を超えているならスルーされる(UCharacterMovementComponentの場合はカプセルの半分サイズを高さとして使用されてます) |
Engin.iniにAvoidanceManagerを指定することができるためプロジェクト用AvoidanceManagerを登録することは可能です。
1 2 |
[/Script/Engine.Engine] AvoidanceManagerClassName=/Script/Engine.AvoidanceManager |
なのでずがこのAvoidanceManagerの関数はほぼvirtualがなかったりで有用ではないかもしれません…
Velocityを調整したい場合はUCharacterMovementComponentに限っては変数「bUseRVOPostProcess」をTrueにすることで関数「PostProcessAvoidanceVelocity」が使用できるのでこれを使用すればエンジン修正せずVelocityの調整が可能かと思います。
簡単ではありますがAvoidanceManagerについての紹介は以上となります、また機会があればCrowdManagerとの比較などやってみたいと思います。
少しでも皆様の開発に役立てばと思います。
ここまで読んでいただきありがとうございました。
CrowdManagerの特徴や使用方法などはこちらを参考にさせていただきました。
https://qiita.com/EGJ-Ken_Kuwano/items/120901d259467568e4f7
RVOに関しては以下のものを参考にさせていただきました。
https://qiita.com/Dv7Pavilion/items/5ef3cc4e95463027219a
CharacterMovementComponentの場合、すでにIRVOAvoidanceInterfaceを継承しておりGetRVOAvoidanceOriginで返している位置は
キャラクターのカプセルの足元位置を返すようにしています。