| | | 1 | | using UnityEngine; |
| | | 2 | | |
| | | 3 | | // Geometric escape detector. |
| | | 4 | | // |
| | | 5 | | // The geometric escape detector checks whether the agent is between the threat and its target. |
| | | 6 | | public class GeometricEscapeDetector : EscapeDetectorBase { |
| | | 7 | | // The range buffer factor allows the interceptor to be slightly further away from the target than |
| | | 8 | | // the target is to its target before declaring an escape. |
| | | 9 | | private const float _rangeBufferFactor = 1.1f; |
| | | 10 | | |
| | 42 | 11 | | public GeometricEscapeDetector(IAgent agent) : base(agent) {} |
| | | 12 | | |
| | 0 | 13 | | public override bool IsEscaping(IHierarchical target) { |
| | 0 | 14 | | if (target == null) { |
| | 0 | 15 | | return false; |
| | | 16 | | } |
| | | 17 | | |
| | 0 | 18 | | Transformation agentToTargetTransformation = Agent.GetRelativeTransformation(target); |
| | | 19 | | |
| | | 20 | | // Check if the target has a target of its own. |
| | 0 | 21 | | if (target.Target != null && !target.Target.IsTerminated) { |
| | 0 | 22 | | Vector3 targetRelativePositionToTarget = target.Target.Position - target.Position; |
| | | 23 | | // The target is escaping if the distance from the agent to the target is greater than the |
| | | 24 | | // distance from the target to its target or if the agent is geometrically behind the target |
| | | 25 | | // relative the target's own target. |
| | 0 | 26 | | return agentToTargetTransformation.Position.Range > |
| | | 27 | | targetRelativePositionToTarget.magnitude * _rangeBufferFactor || |
| | | 28 | | Vector3.Dot(-agentToTargetTransformation.Position.Cartesian, |
| | | 29 | | targetRelativePositionToTarget) < 0; |
| | | 30 | | } |
| | | 31 | | |
| | | 32 | | // Fall back to checking the relative velocity. |
| | 0 | 33 | | return agentToTargetTransformation.Velocity.Range < 0; |
| | 0 | 34 | | } |
| | | 35 | | } |