This document is about: QUANTUM 3
SWITCH TO

This page has not been upgraded to Quantum 3.0 yet. The information may be out of date.

エージェントの回避

回避エージェントの設定

シミュレーション設定を開いて確認してください:AvoidanceRange は回避システムの品質とパフォーマンスコストにとって重要です。これは、エージェントが互いに影響を及ぼし始める範囲を定義します。この範囲は、2 つのエージェントの半径間で測定されます。

MaxAvoidanceCandidates は、各エージェントが使用する回避候補の最大数を定義します。候補が多いほど、メモリと CPU 時間をより多く消費しますが、エージェントが多い場合には質を向上させます。まずは数を減らして、実際にどれだけ少なくて済むかを確認してください。AvoidanceQuality が高く、互いに出会うエージェントが多いほど、この数は高くする必要があります。

EnableAvoidance をオフに設定すると、パスファインダーやステアリングエージェントを持っていても回避を使用しないことになります。これにより回避タスクがスケジュールされなくなるため、パフォーマンスが最適化されます。これは NavigationSystemSystemSetup.cs から完全に削除されていない場合には必須ではありません。

Simulation Config

回避を有効にするには、NavMeshAvoidanceAgent コンポーネントを NavMeshPathfinder および NavMeshSteeringAgent コンポーネントをすでに持つエンティティに追加します。

次に、NavMeshAgentConfig の回避セクションを設定します:

AvoidanceType.None に設定すると、エージェントは他のエージェントを回避しなくなりますが、他のエージェントはエージェントを回避します。これは NavMeshAvoidanceObstacle コンポーネントのように機能します。

Priority は Unity と同様に動作します。最も重要なものが 0 で、最も重要度が低いものが 99 です。デフォルトは 50 です。回避システムは相互依存性によるため、回避作業(誰が誰を回避するか、どれほど回避するか)は常にエージェント間で分担されます。優先度が高いエージェントは、作業を 25% のみ行い、同じ優先度のエージェント同士では作業を 50/50 で分担します。

Unity のレイヤーを使用し、AvoidanceLayerAvoidanceMask を設定してエージェントをフィルタリングします。例えば、いくつかのエージェントを Heroes レイヤーに配置し、他のエージェントを Minions レイヤーに配置し、Heroes に対して Minions を無視するマスクを設定します。

OverrideRadiusForAvoidance をオンにすると、パスファインディングやステアリングで使用される Radius とは異なる Radius を回避用に設定できます。

エージェントがウェイポイントを追跡し、コーナーを回ったり狭い通路を通過する際にも回避を解決しなければならないため、問題が発生することがあります。この問題を軽減し、エージェントが互いにブロックし合うのを防ぐために、ReduceAvoidanceAtWaypoints をオンにします。エージェントがウェイポイントに近づくときに適用される回避が減少します。ReduceAvoidanceFactor 値はエージェントの半径と掛け合わされ、回避の影響が二次的に減少する距離を表します。

DebugAvoidance をオンにすると、シーンビューにギズモが描画されます。上部の回避エージェントは、右側の移動エージェントを回避し、左側の障害物を避けています。赤いコーンは上部のエージェントの速度障害物であり、緑の線は候補を示し、最後に白い点は選ばれた候補です。静的オブジェクトの VO は切り捨てられます(この件については、Navigation.Constants.VelocityObstacleTruncationFactor を参照して調整可能です)。

Avoidance Agent Debug Gizmos
Quantum Agent Avoidance

回避障害物の設定

Avoidance Obstacles は、Navmesh エージェントの回避動作に影響を与える静的または動的エンティティですが、自身はエージェントではありません。これらはパスファインダーには影響を与えず、ゲームレベルの一部をブロックするために使用されるべきではありません。

NavMeshAvoidanceObstacle コンポーネントは、正常に動作するために Transform2D/3D コンポーネントを必要とします。

NavMeshAvoidanceObstacle コンポーネントを持つエンティティが移動している場合、他のエージェントはその速度情報が必要であり、将来の位置を予測します。このプロパティ NavMeshAvoidanceObstacle.Velocity を定期的に手動で更新することを確認してください。

回避障害物を設定するには:

  • Unity の EntityPrototype コンポーネントとして:
Avoidance Obstacle Prototype
  • または、ソースコード内の Quantum コンポーネントとして:

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);

ジッタリングエージェント

異なる方向に動いている複数のエージェントと回避を解決すると、エージェントは良いコースを見つけるまで方向を非常に迅速に切り替えることがあります。これを軽減するために、エージェントの Angular Speed を減らすか、ビュー内で QuantumEntityView をオーバーライドして追加のスムージングを適用できます。ブレンディングの数式はあくまで一例です。

C#

using UnityEngine;

public class SmoothRotationEntityView : QuantumEntityView {
  private Quaternion rotation;
  public float Blending;

  protected override void ApplyTransform(ref UpdatePostionParameter param) {
    // 新しい位置がどのようにトランスフォームに適用されるかを変更するためにサブクラスでこれをオーバーライドします。
    transform.position = param.NewPosition + param.ErrorVisualVector;

    // Unity のクォータニオンの乗算は、rhs を適用した後に lhs を適用するのが同等です(そのドキュメントでは反対と言っていますが)。
    rotation = param.ErrorVisualQuaternion * param.NewRotation;
    transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * Blending);
  }
}
Back to top