エージェント回避
Quantumには、Hybrid Reciprocal Velocity Obstacles とよばれる衝突回避技術の種類が実装されています。内部の動作の詳細についてはこちらの記事を参照ください。: Reciprocal Collision Avoidance and Navigation for Video Games
回避エージェントを設定する
シミュレーションコンフィグを開き、レビューを行います。回避システムのクオリティやパフォーマンスコストについて、AvoidanceRange
が重要なカギとなります。エージェントがお他愛に影響を与え始める範囲を定義します。範囲は、2つのエージェント間の半径で測定されます。
MaxAvoidanceCandidates
は、各エージェントが使用する回避候補の最大数を定義します。候補が多いほど、要求されるメモリやCPU時間も大きくなりますが、使用するエージェントの数が増えるとクオリティも上がります。はじめに数を減らた状態で、どれだけうまくやるのが難しいか見てみてください。AvoidanceQuality
や互いに出会うエージェントの数が多ければ、MaxAvoidanceCandidates
の必要数も多くなります。
パスファインダーとステアリングが必要な場合、EnableAvoidance
をオフに設定します。ただし、回避は使用しないでください。回避タスクがスケジューリングされないため、パフォーマンスが最適化されます。NavigationSystem
が完全にSystemSetup.cs
から削除されている場合、この設定は必要ありません。
回避を有効にするには、NavMeshAvoidanceAgent
コンポーネントを、NavMeshPathfinder
コンポーネント および NavMeshSteeringAgent
コンポーネントを既にもつエンティティに追加します。
その後、NavMeshAgentConfig
の回避セクションを設定します。以下を参照ください。
AvoidanceType.None
には、あるエージェントが他のエージェントを回避しなくなるが、その他のエージェントはそのエージェントを回避する、という効果があります。NavMeshAvoidanceObstacle
コンポーネントによく似ています。
Priority
はUnityと同じように動作します。もっとも重要なものは0、重要度が最も低いものは99となり、デフォルトは50です。回避システムがreciprocalityに依存するため、回避動作(誰が誰をどのくらい回避するか)は常にエージェント間で別れます。同じ優先度のエージェントは回避動作を50/50に分割しますが、優先度の高いエージェントは回避動作の25%のみを実行します。
Unityレイヤーを使用してAvoidanceLayer
とAvoidanceMask
を設定し、エージェントをフィルタリングします。例えば、エージェントのうちいくつかをHeroes
レイヤーに設定し、他のエージェントをMinions
レイヤーに設定します。そしてHeroesにMinionsを無視するようマスクを掛けます。
回避するのにパスファインディングやステアリングに使用したのとは別のRadius
を使用する場合は、OverrideRadiusForAvoidance
をトグルします。
回避を解消しつつ、ウェイポイントをフォローしてコーナーを避けたり、狭い通路を通り抜けたりするのは困難です。お互いにブロックしているエージェントの有利になるように、問題を軽減して視覚的なオーバーラップを受け入れるには、ReduceAvoidanceAtWaypoints
をトグルします。エージェントがウェイポイントに近づいた際に適用された回避は減ります。ReduceAvoidanceFactor
の値はエージェントの半径で倍増し、回避の影響が二次式的に少なくなった距離を表しています。
DebugAvoidance
をトグルしてギズモをシーンビューにレンダリングします。一番上にある回避エージェントはエージェントの右側で動いているエージェントと左側にある障害物を回避しています。赤いコーンは上にあるエージェントのVelocity Obstaclesで、緑の線は候補、白い点は選ばれた候補です。動かない物体のVelocity Obstaclesは切り落とされます(これについてはNavigation.Constants.VelocityObstacleTruncationFactor
を参照してください)。
回避障害物を設定する
Avoidance Obstacles(回避障害物)
は静止または移動するエンティティで、Navmeshエージェントの回避動作に影響を与えますが、エージェントではありません。NavMeshAvoidanceObstacle
コンポーネントが NavMeshAvoidanceAgent
を持つエンティティに追加されるとアサーションが投げられます。
- UnityのEntityPrototypeコンポーネントとして
- ソースコード内のQuantumkんぽーネントとして
C#
var c = f.Create();
f.Set(c, new Transform2D { Position = position });
var obstacle = new NavMeshAvoidanceObstacle();
obstacle.AvoidanceLayer = 0;
obstacle.Radius = FP._0_50;
obstacle.Velocity = FPVector2.Up;
f.Set(c, obstacle);
障害物が動いている場合、他のエージェントは速度情報を使用して将来の位置を予測できます。その場合、定期的にNavMeshAvoidanceObstacle.Velocity
を手動で(実際の動作には使いません)アップデートするようにしてください。