| | | 1 | | using System.Collections.Generic; |
| | | 2 | | using UnityEngine; |
| | | 3 | | |
| | | 4 | | // The proximity release strategy decides to launch an interceptor against an incoming target |
| | | 5 | | // depending on the distance and bearing to the target. |
| | | 6 | | public class ProximityReleaseStrategy : MassReleaseStrategyBase { |
| | | 7 | | // Geometric parameters for determining when to launch. |
| | | 8 | | // The carrier interceptor will spawn submunitions when any target is greater than 30 degrees away |
| | | 9 | | // from the carrier interceptor's current velocity or when any threat is within 1000 meters of the |
| | | 10 | | // interceptor. |
| | | 11 | | private const float _maxBearingDegrees = 30f; |
| | | 12 | | private const float _minDistanceToThreat = 1000f; |
| | | 13 | | private const float _maxDistanceToThreat = 2500f; |
| | | 14 | | // TODO(titan): The prediction time should be a function of the sub-interceptor characteristic, |
| | | 15 | | // such as the boost time. |
| | | 16 | | private const float _predictionTime = 0.6f; |
| | | 17 | | |
| | 0 | 18 | | public ProximityReleaseStrategy(IAgent agent, IAssignment assignment) : base(agent, assignment) {} |
| | | 19 | | |
| | 0 | 20 | | protected override LaunchPlan PlanRelease(IEnumerable<IHierarchical> targets) { |
| | 0 | 21 | | foreach (var target in targets) { |
| | 0 | 22 | | var predictor = new LinearExtrapolator(target); |
| | 0 | 23 | | PredictorState predictedState = predictor.Predict(_predictionTime); |
| | 0 | 24 | | Vector3 positionToPredictedTarget = predictedState.Position - Agent.Position; |
| | 0 | 25 | | float predictedDistanceToTarget = positionToPredictedTarget.magnitude; |
| | | 26 | | |
| | | 27 | | // Check whether the distance to the target is less than the minimum distance. |
| | 0 | 28 | | if (predictedDistanceToTarget < _minDistanceToThreat) { |
| | 0 | 29 | | return new LaunchPlan { ShouldLaunch = true }; |
| | | 30 | | } |
| | | 31 | | |
| | | 32 | | // Check whether the bearing exceeds the maximum bearing. |
| | 0 | 33 | | float lateralDistance = |
| | | 34 | | (Vector3.ProjectOnPlane(positionToPredictedTarget, Agent.Velocity)).magnitude; |
| | 0 | 35 | | float sinBearing = Mathf.Clamp01(lateralDistance / predictedDistanceToTarget); |
| | 0 | 36 | | float bearing = Mathf.Asin(sinBearing) * Mathf.Rad2Deg; |
| | 0 | 37 | | if (bearing > _maxBearingDegrees && predictedDistanceToTarget < _maxDistanceToThreat) { |
| | 0 | 38 | | return new LaunchPlan { ShouldLaunch = true }; |
| | | 39 | | } |
| | 0 | 40 | | } |
| | 0 | 41 | | return LaunchPlan.NoLaunch(); |
| | 0 | 42 | | } |
| | | 43 | | } |