// Call all planners in order and return the flightTime if at least one planner // found a solution. The return value is only true if the last planner that found a // plan had mayLaunch = true. private static bool RunPlanners(ICollection <TrajectoryPlannerBase> planners, ProjectileKinematics projectileKinematics, Vector3 predictedLauncherPosition, Vector3 predictedTargetPosition, out float flightTime) { Projectile3D projectile3D = projectileKinematics.Projectile3D; flightTime = 0; bool mayLaunch = false; foreach (TrajectoryPlannerBase planner in planners) { if (planner.PlanTimeToTarget(projectile3D, predictedLauncherPosition, predictedTargetPosition, ref flightTime)) { mayLaunch = planner.mayLaunch; } } return(mayLaunch); }
// Based on the incoming positions, velocities and timing information, this function // uses dead reckoning to work out the TrajectoryXXXPlanner inputs to plan plan the // next projectile's trajectory with. The planners are called from lo to high // PlanNumber. If any (future) plan is available, it returns the initial velocity for // that plan. Otherwise, it returns Vector3.Zero. Furthermore, if a future plan is // found AND it allows launching AND the target is within reach AND // minimumTimeToNextLaunch <= 0, then shouldLaunch = true. public static Vector3 UpdatePlan(ICollection <TrajectoryPlannerBase> planners, ProjectileKinematics projectileKinematics, Vector3 launcherPosition, Vector3 launcherVelocity, Vector3 targetPosition, Vector3 targetVelocity, float minimumTimeToNextLaunch, ref float lastFlightTime, out bool shouldLaunch) { // Work out where the launcher and the target are most likely to be when // minimumTimeToNextLaunch becomes zero again. minimumTimeToNextLaunch = Mathf.Max(0.0f, minimumTimeToNextLaunch); float timeToTarget = minimumTimeToNextLaunch + lastFlightTime; Vector3 predictedLauncherPosition = launcherPosition + launcherVelocity * minimumTimeToNextLaunch; Vector3 predictedTargetPosition = targetPosition + targetVelocity * timeToTarget; // Run the planners bool mayLaunch = RunPlanners(planners, projectileKinematics, predictedLauncherPosition, predictedTargetPosition, out lastFlightTime); // Calculate the projectile spawn velocity if a flight time estimate is available Vector3 projectileVelocity = Vector3.zero; if (lastFlightTime > 0) { Projectile3D projectile3D = projectileKinematics.Projectile3D; projectileVelocity = projectile3D.GetInitialVelocityGivenRelativeTargetAndTime( predictedTargetPosition - predictedLauncherPosition, lastFlightTime); } // Set shouldLaunch to true iff the planners presented a plan and // the time is right. shouldLaunch = mayLaunch && minimumTimeToNextLaunch <= 0; return(projectileVelocity); }
// Based on the incoming positions, velocities and timing information, this function // uses dead reckoning to work out the TrajectoryXXXPlanner inputs to plan plan the // next projectile's trajectory with. The planners are called from lo to high // PlanNumber. If any (future) plan is available, it returns the initial velocity for // that plan. Otherwise, it returns Vector3.Zero. Furthermore, if a future plan is // found AND it allows launching AND the target is within reach AND // minimumTimeToNextLaunch <= 0, then shouldLaunch = true. public static Vector3 UpdatePlan(ICollection<TrajectoryPlannerBase> planners, ProjectileKinematics projectileKinematics, Vector3 launcherPosition, Vector3 launcherVelocity, Vector3 targetPosition, Vector3 targetVelocity, float minimumTimeToNextLaunch, ref float lastFlightTime, out bool shouldLaunch) { // Work out where the launcher and the target are most likely to be when // minimumTimeToNextLaunch becomes zero again. minimumTimeToNextLaunch = Mathf.Max(0.0f, minimumTimeToNextLaunch); float timeToTarget = minimumTimeToNextLaunch + lastFlightTime; Vector3 predictedLauncherPosition = launcherPosition + launcherVelocity * minimumTimeToNextLaunch; Vector3 predictedTargetPosition = targetPosition + targetVelocity * timeToTarget; // Run the planners bool mayLaunch = RunPlanners(planners, projectileKinematics, predictedLauncherPosition, predictedTargetPosition, out lastFlightTime); // Calculate the projectile spawn velocity if a flight time estimate is available Vector3 projectileVelocity = Vector3.zero; if (lastFlightTime > 0) { Projectile3D projectile3D = projectileKinematics.Projectile3D; projectileVelocity = projectile3D.GetInitialVelocityGivenRelativeTargetAndTime( predictedTargetPosition - predictedLauncherPosition, lastFlightTime); } // Set shouldLaunch to true iff the planners presented a plan and // the time is right. shouldLaunch = mayLaunch && minimumTimeToNextLaunch <= 0; return projectileVelocity; }
// if the barrel is misaligned with the // latest plan. void Start() { _projectileKinematics = launchProjectile.GetComponent<ProjectileKinematics>(); _planners = TurretHelper.SortPlanners( GetComponents<TrajectoryPlannerBase>()); _pitchMotorControl = GetComponentInChildren<PitchMotorControl>(); _yawMotorControl = GetComponentInChildren<YawMotorControl>(); _barrelRecoil = GetComponentInChildren<BarrelRecoil>(); _aimForwardAxis = launchTransform.forward; }
// Call all planners in order and return the flightTime if at least one planner // found a solution. The return value is only true if the last planner that found a // plan had mayLaunch = true. private static bool RunPlanners(ICollection<TrajectoryPlannerBase> planners, ProjectileKinematics projectileKinematics, Vector3 predictedLauncherPosition, Vector3 predictedTargetPosition, out float flightTime) { Projectile3D projectile3D = projectileKinematics.Projectile3D; flightTime = 0; bool mayLaunch = false; foreach (TrajectoryPlannerBase planner in planners) { if (planner.PlanTimeToTarget(projectile3D, predictedLauncherPosition, predictedTargetPosition, ref flightTime)) { mayLaunch = planner.mayLaunch; } } return mayLaunch; }