エージェントの回避
Quantumは、**Hybrid Reciprocal Velocity Obstacles (HRVO)**と呼ばれる衝突回避技術の一種を実装してしています。
回避エージェントのセットアップ
NavMeshAvoidanceAgentコンポーネントは、エンティティにNavMeshPathfinderとNavMeshSteeringAgentコンポーネントが両方付いている必要があります。
Simulation Config
回避を行うには、SimulationConfigのNavigationセクションから、以下のグローバルパラメーターを設定する必要があります。
EnableAvoidanceを無効にすると、回避システムのオーバーヘッドが完全に取り除かれます。
AvoidanceRangeは、回避システムの品質とパフォーマンスコストに非常に大きな影響を与えます。これは、エージェント同士が相互に影響を与え始める範囲を定義します。「A」は各エージェントの回避半径、「B」はエージェントの回避半径にグローバルなAvoidanceRangeを追加した半径です。
inRange = Distance(positionAgentA, positionAgentB) - radiusAgentA - radiusAgentB < AvoidanceRange
MaxAvoidanceCandidatesは、各エージェントが使用する最大回避候補数を定義します。候補数が増えると、CPUとメモリ使用量も増えますが、品質も向上します。AvoidanceQualityが高く、相互に影響するエージェントが多いほど、この値も大きくする必要があります。
VelocityObstacleTruncationFactorは、動的障害物(VO)をどれだけ静的障害物として切り捨てるかを定義します。
NavMeshAgentConfig - 回避
| AvoidanceType | エージェントの回避モードを設定します。
None = エージェントは他のエージェントを回避しませんが、他のエージェントはこのエージェントを回避します。Internal = 内部の回避システムを使用して、エージェントはアクティブに他のエージェントを積極的に回避します。 |
| AvoidanceQuality | エージェントの回避品質を設定します。品質が高いほど、他のエージェントを回避するために多くの候補が計算されます。
Fast = 最小の回避候補のみが計算されます。Good = 最適な費用対効果が得られる妥当な候補数が計算されます。Best = 衝突が発生しない最大候補数が生成されます。 |
| Priority | エージェントのPriorityは、Unityと同様に動作します。
デフォルト = 50最重要 = 0重要でない = 99
回避システムは相互性に依存するため、回避動作(誰が誰をどの程度回避するのか)は常にエージェント間で分担されます。優先度が高いエージェントは動作の 25%のみを担当し、優先度が同じエージェント同士は動作を50/50で分担します。 |
| AvoidanceRadius | エージェントの回避半径は、キャラクターのビジュアルサイズにおおむね合わせる必要があります。
これは SimulationConfigの回避半径と合わせて、相互に影響するエージェントのペアを作成する回避ブロードフェーズで使用されます。 |
| AvoidanceLayer | エージェントの回避レイヤーを設定します。
Unityレイヤーは、 AvoidanceLayerとAvoidanceMaskでエージェントをフィルタリングするために使用されます。 |
| AvoidanceMask | エージェントの回避マスクを設定します。マスクに含まれないAvoidanceLayerを持つエージェントは無視されます。 |
| MaxAvoidanceCandidates | エージェントの最大回避候補数を設定します。グローバルな最大値はSimulationConfigで設定されます。 |
| ReduceAvoidanceAtWaypoints | ウェイポイントに従いながら角を曲がったり狭い通路を通りながら、回避行動を解決することは困難です。この問題を緩和し、エージェント同士がぶつかり合うビジュアルの重なりを許容するには、ReduceAvoidanceAtWaypointsを切り替えてください。 |
| ReduceAvoidanceFactor | エージェントがウェイポイントに接近した際の回避動作が減少します。ReduceAvoidanceFactor値はエージェントの半径と乗算されて、回避の影響が二次的に減少する距離を表します。 |
| AvoidanceCanReduceSpeed | このオプションによってエージェントの速度を低下させることで、回避動作をより自然に見せることができます。 |
| ShowDebugAvoidance | 動的障害物とその候補が、実行時にギズモとして表示されるかどうかを定義します。 |
回避障害物のセットアップ
Avoidance Obstacles(回避障害物)は、ナビメッシュエージェントの回避動作に影響を与える静的/動的なエンティティですが、それ自体はエージェントではありません。これは経路探索には影響を与えないため、レベルの一部をブロックするために使用すべきではありません。
NavMeshAvoidanceObstacleコンポーネントを正しく動作させるには、Transform2D/Transform3Dコンポーネントが必要です。
NavMeshAvoidanceObstacleコンポーネントを持つエンティティが移動する場合、他のエージェントは将来の位置を予測するための速度情報が必要になるため、NavMeshAvoidanceObstacle.Velocityを手動で設定する必要があります。
NavMeshAvoidanceObstacleは、UnityのQuantumエンティティプロトタイプから追加できます。
または、コードから追加できます。
C#
var c = f.Create();
f.Set(c, new Transform2D { Position = new FPVector2(8,-2) });
var obstacle = new NavMeshAvoidanceObstacle();
obstacle.AvoidanceLayer = 0;
obstacle.Radius = FP._0_50;
obstacle.Velocity = FPVector2.Zero;
f.Set(c, obstacle);
エージェントのジッター(揺らぎ)
エージェントの移動、特に移動方向は、回避計算の性質と固定小数点演算との組み合わせによって、不安定になる可能性があります。これによって、エージェントのビジュアルにジッター(揺らぎ)が発生します。
これを軽減するには、エージェントのAngular Speedを調整するか、ビューのスムージングを追加しましょう。これは、QuantumEntityViewクラスをオーバーライドして、transform適用時に回転をブレンディングすることで実現できます。
C#
namespace Quantum {
using UnityEngine;
public class SmoothRotationEntityView : QuantumEntityView {
public float Blending = 15;
private Quaternion rotation;
protected override void ApplyTransform(ref UpdatePositionParameter param) {
// サブクラスでこれをオーバーライドして、transformに新しい位置を適用する方法を変更する
transform.position = param.NewPosition + param.ErrorVisualVector;
// UnityのQuaternion乗算は右辺から左辺に適用される(公式ドキュメントは逆に記載されているが)
rotation = param.ErrorVisualQuaternion * param.NewRotation;
transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * Blending);
}
}
}
Back to top