API.Ballistics

The Ballistics class (namespace Heathen.UnityPhysics.API) offers a comprehensive set of static methods for solving projectile‐motion problems in both 3D and 2D contexts. Designers and programmers can use these utilities to:

  • Estimate maximum range or required speed/angle.

  • Compute flight time or final velocity for a given trajectory.

  • Solve for launch rotations (low/high arc) toward stationary or moving targets.

  • Generate full, sampled trajectories via raycasts or spherecasts that account for gravity or other constant accelerations.

Below is a grouped reference of all public methods, with usage notes, parameter descriptions, and practical tips.


1. Maximum Range & Flight Time

1.1 MaxRange (3D)

public static float MaxRange(float speed, float gravity, float height)
  • Purpose: Returns the maximum horizontal distance (range) reachable when launching at 45° from a given height, ignoring air resistance.

  • Parameters:

    • speed (float): Initial launch speed (> 0).

    • gravity (float): Gravity magnitude (> 0).

    • height (float): Launch‐point height above the landing plane (≥ 0).

  • Returns:

    • Maximum range (units), or 0 if invalid inputs (speed ≤ 0, gravity ≤ 0, or height < 0).

  • Usage:

    • Quickly gauge how far a cannonball or grenade would travel when fired at 45°.

    • Clamp AI or camera aiming—e.g., if targetDistance > MaxRange(speed, 9.81f, muzzleHeight), skip the shot.


  • Purpose: Finds a positive flight time t such that the projectile, launched from start with initial velocity and subjected to constantAcceleration, arrives at end.

  • Parameters:

    • start, end (Vector3): World‐space start and end positions.

    • velocity (Vector3): Initial velocity vector.

    • constantAcceleration (Vector3): Constant acceleration (e.g., (0, –9.81f, 0)).

    • tolerance (float): Maximum allowed error when comparing solutions on each axis (default 0.01).

  • Returns:

    • A positive flight time (seconds) if a consistent solution across X/Y/Z axes is found; otherwise float.NaN.

  • Usage:

    • Determine “time to impact” given a known launch vector—useful for synchronizing timed effects.

    • Validate a precomputed trajectory—if FlightTime(...) returns NaN, there is no way to reach end with the given inputs.


1.3 FlightTime2D (2D)

  • Purpose: Same as FlightTime but in the X/Y plane (2D).

  • Parameters:

    • start, end (Vector2): 2D start and end positions.

    • velocity (Vector2): Initial 2D velocity.

    • constantAcceleration (Vector2): 2D acceleration.

    • tolerance (float): Allowed difference between X and Y solutions (default 0.01).

  • Returns:

    • Positive flight time if a consistent solution exists; otherwise NaN.

  • Usage:

    • Pinpoint when a 2D projectile reaches a specific point (e.g., for triggering splash effects).


1.4 FinalVelocity (3D)

  • Purpose: Computes the final velocity after time flightTime under constant acceleration.

  • Returns: initialVelocity + constantAcceleration * flightTime.

  • Usage:

    • After computing flight time via FlightTime, call this to know the speed/direction at impact.


1.5 FinalVelocity2D (2D)

  • Purpose: 2D analog of FinalVelocity.

  • Returns: initialVelocity + constantAcceleration * flightTime.


2. Launch‐Angle Solutions (Stationary Targets)

These methods solve for one or two possible launch rotations (quaternions) that send a projectile from projectile to target, given speed or gravity. They return the number of valid solutions (0, 1, or 2), and output lowAngle (flatter trajectory) and highAngle (steeper trajectory). In 3D, you can supply a full acceleration vector; in 2D, analogous methods operate on Vector2.


2.1 Solution (3D with Constant Acceleration)

  • Purpose: Solves for low‐ and high‐arc launch rotations when acceleration may not be purely vertical (e.g., gravity + wind).

  • Algorithm:

    1. Rotate world so constantAcceleration aligns with (0, –1, 0).

    2. Solve 2D problem in that space with scalar gravity = ‖constantAcceleration‖.

    3. Rotate solutions back to original space.

  • Parameters:

    • projectile, target: World‐space positions.

    • speed: Scalar launch speed (> 0).

    • constantAcceleration: Any nonzero acceleration vector.

  • Returns:

    • 0 if no solutions (e.g., out of range or zero acceleration), 1 if a single tangent, or 2 if two distinct arcs exist.

    • lowAngle/highAngle are set to identity if no solutions; otherwise, the corresponding quaternions.

  • Usage:

  • Designer Tips:

    • Use low‐arc (lowAngle) for faster, direct shots.

    • Use high‐arc (highAngle) for lobbed trajectories (e.g., launching over obstacles).


2.2 Solution2D (2D with Constant Acceleration)

  • Purpose: 2D equivalent of the above, returning quaternions whose forward vector lies in the XY‐plane.

  • Parameters:

    • projectile, target (Vector2): 2D start and end.

    • constantAcceleration: Typically (0, –gravity).

  • Returns:

    • Number of solutions (0, 1, or 2).

    • lowAngle, highAngle quaternions (their “forward” points in the 2D direction of launch).

  • Usage:


2.3 Solution (3D with Gravity Scalar)

  • Purpose: Classic 3D ballistic‐trajectory solver assuming vertical gravity of magnitude gravity. Returns quaternions for low/high launch angles.

  • Parameters:

    • projectile, target: World‐space positions.

    • speed: Initial speed (> 0).

    • gravity: Gravity magnitude (> 0).

  • Returns:

    • 0 if no real solutions (target out of range), 1 if tangent, or 2 if two distinct arcs.

    • lowAngle = flatter arc; highAngle = steeper arc.

  • Usage:


2.4 Solution2D (2D with Gravity Scalar)

  • Purpose: 2D analog of the 3D‐gravity solver.

  • Returns: Low/high quaternions whose forward axis is (0,0,1) and “up” is the 2D launch vector in XY.

  • Usage:


3. Aiming Solutions (Moving Targets)

When the target moves with a constant velocity, these methods solve a quartic equation for time of intercept and compute the corresponding launch directions. They support both 3D and 2D.


3.1 Solution (3D, Moving Target)

  • Purpose: Finds up to two valid launch rotations that intercept a target moving at targetVelocity under scalar vertical gravity.

  • Algorithm:

    1. Build quartic coefficients for intercept time t based on relative positions and velocities (derived from “lib_fts” formulas).

    2. Solve quartet for positive roots.

    3. For each positive root t, compute required launch velocity vector.

    4. Convert those direction vectors into quaternions (Quaternion.LookRotation(...)).

  • Parameters:

    • projectile, target: Initial positions.

    • speed: Launch speed.

    • targetVelocity: Constant world‐space velocity of the target.

    • gravity: Gravity magnitude (> 0).

  • Returns:

    • Count count of valid launch‐vectors (0, 1, or 2).

    • lowAngle = first solution; highAngle = second solution if present, otherwise same as lowAngle.

  • Usage:


3.2 Solution2D (2D, Moving Target)

  • Purpose: 2D counterpart for a moving target on the X/Y plane under vertical gravity.

  • Returns:

    • Number of valid solutions (0, 1, 2).

    • Quaternions whose forward is (0,0,1) and up‐vector corresponds to the required 2D launch vector.

  • Usage:


4. Arc‐Ceiling Solutions (Fixed and Moving Targets)

These methods compute the initial velocity vector and required gravity to satisfy a specified “maximum height” (arc ceiling) along the trajectory, solving a system of equations that force the apex of the parabola to reach arcCeiling. Both 3D and 2D variants exist, for stationary and moving targets.


4.1 Solution (3D, Prescribed Arc Ceiling, Stationary Target)

  • Purpose: Given a desired apex height (arcCeiling) and constant horizontal speed (linearSpeed), finds the vertical component of the initial velocity and gravity value needed to pass through that apex and land at target.

  • Parameters:

    • projectile, target: World‐space start and end.

    • linearSpeed: Speed along the horizontal plane (XZ).

    • arcCeiling: Desired maximum height (absolute Y value) of the trajectory, must be > projectile.y.

  • Outputs:

    • firingVelocity: Vector3 launch velocity (combining horizontal direction and vertical component).

    • gravity: Negative gravity scalar required to achieve that apex.

  • Returns: true if a valid solution exists; false otherwise (e.g., projectile == target, arcCeiling ≤ projectile.y, or zero horizontal distance).

  • Usage:


4.2 Solution2D (2D, Prescribed Arc Ceiling, Stationary Target)

  • Purpose: Same as above, but in 2D (X/Y).

  • Usage:


4.3 Solution (3D, Prescribed Arc Ceiling, Moving Target)

  • Purpose: Computes initial firingVelocity and gravity so the projectile intercepts a moving target at a trajectory whose apex is arcCeiling above max(startY, targetY). Also returns the computed impactPoint accounting for movement.

  • Parameters:

    • projectile: Launch position.

    • linearSpeed: Horizontal speed on the XZ plane (no vertical component).

    • target, targetVelocity: Initial position and velocity of the moving target.

    • arcCeiling: Desired apex height above “ground”—calculated as max(projectile.y, impactPoint.y) + arcCeiling.

  • Outputs:

    • firingVelocity (Vector3): Initial velocity (both horizontal and vertical components).

    • gravity (float): Negative gravity scalar needed.

    • impactPoint (Vector3): World‐space point where the projectile collides, given the target’s motion.

  • Returns: true if a valid intercept solution exists; false otherwise.

  • Usage:


4.4 Solution2D (2D, Prescribed Arc Ceiling, Moving Target)

  • Purpose: 2D version of the moving‐target, prescribed apex solver.

  • Usage:


5. Flight‐Time Specified Solutions

When you know exactly how long you want the projectile to be in flight (e.g., for timing or syncing purposes), these methods compute the required initial velocity to land at target after a fixed flightTime under a constant gravity.


5.1 Solution (3D, Flight Time Specified)

  • Purpose: Returns the initial velocity vector that sends a projectile from projectile to target in exactly flightTime, under vertical gravity of magnitude gravity.

  • Parameters:

    • projectile, target: World positions.

    • gravity: Gravity scalar (negative or positive? It uses gravity as is, so typically pass a negative value, e.g., -9.81f).

    • flightTime: Desired time to impact (> 0).

  • Returns:

    • A Vector3 whose horizontal components (x,z) equal horizontalDistance / flightTime, and whose vertical component solves y0 + vy*t + 0.5*gravity*t^2 = y1.

  • Usage:


5.2 Solution2D (2D, Flight Time Specified)

  • Purpose: 2D analog (X/Y) for fixed flightTime.

  • Returns: Vector2(horizontalVelocity, verticalVelocity).

  • Usage:


6. Speed‐Given‐Angle Solutions

These methods compute the necessary launch speed (magnitude) to hit a target from projectile when the launch direction is constrained to a fixed angle angleDegrees above the horizontal.


6.1 Solution (3D, Speed Given Angle)

  • Purpose: With a fixed elevation angleDegrees (above the horizontal plane), computes the required scalar speed so the projectile reaches target under vertical gravity of magnitude gravity.

  • Parameters:

    • projectile, target: Start and end positions.

    • angleDegrees: Launch angle from horizontal (0–90).

    • gravity: Gravity magnitude (> 0).

  • Outputs:

    • speed: Required launch speed.

  • Returns: true if a valid (real) solution exists; false otherwise (e.g., denominator ≥ 0 or range = 0).

  • Usage:


6.2 Solution2D (2D, Speed Given Angle)

  • Purpose: 2D version for a fixed launch angle in X/Y.

  • Returns:

    • Required speed magnitude, combining horizontal component z and vertical component y.

  • Usage:


7. Trajectory Marching (Raycast & SphereCast)

These methods allow you to “march” a projectile along its path—applying constant acceleration at each step—and perform either raycasts or spherecasts to detect collisions. They return both the impact (if any) and a sampled path of (position, velocity, time) tuples.


7.1 Raycast (3D)

  • Purpose: Step through a parabolic path, using a symmetric ray at each segment of length resolution, to detect the first collision.

  • Parameters:

    • start: Starting position (Vector3).

    • velocity: Initial launch vector.

    • constantAcceleration: Gravity or other acceleration.

    • resolution: Step length between raycasts (e.g., 0.1f).

    • maxLength: Maximum total arc‐length to march.

    • collisionLayers: LayerMask for collision detection.

  • Outputs:

    • hit: The RaycastHit if collision occurred (otherwise hit.transform == null).

    • path: A List of tuples (position, velocity, time), starting with (start, velocity, 0f), then each sampled point until impact or until exceeding maxLength.

    • distance: Total distance traveled along the curve before impact (or maxLength if no hit).

  • Returns: true if a collision was detected; false otherwise.

  • Usage:

  • Designer Tips:

    • Use for custom trajectory visualizers or to spawn effects at predicted impact.

    • Remember that smaller resolution values yield smoother curves and more accurate collision detection at higher CPU cost.


7.2 SphereCast (3D)

  • Purpose: Similar to Raycast(...), but uses a sphere of radius radius to detect collisions, checking against collisionLayers with optional trigger inclusion. Temporarily disables startCollider at the very beginning to avoid self‐hits.

  • Parameters:

    • startCollider: The Collider to disable at launch until the projectile moves beyond its radius, preventing immediate self‐collision. May be null.

    • All others match Raycast(...) with the addition of radius and queryTriggerInteraction.

  • Usage:


7.3 Raycast2D (2D)

  • Purpose: Marches a 2D projectile along its XY path via Physics2D.Raycast at each step of length resolution, accumulating (position, velocity, time) samples until impact or until the traveled distance ≥ maxLength.

  • Usage:


7.4 CircleCast (2D)

  • Purpose: 2D analog of SphereCast(...). At each incremental step of length resolution, performs Physics2D.CircleCast with radius radius (temporarily disabling startCollider to avoid self‐hit).

  • Usage:


7.5 SphereCast (Simplified Overload, 3D)

  • Purpose: A single‐spherecast version that marches only in one long cast of length maxLength (rather than incremental steps). It still disables startCollider briefly to prevent self‐collision.

  • Behavior:

    1. Disable startCollider.

    2. Perform a single Physics.SphereCast(ray, radius, maxLength, collisionLayers, queryTriggerInteraction).

    3. If hit, compute hitTime = (hitPoint – start).magnitude / velocity.magnitude, add (hitPoint, velocity, hitTime) to path, set distance = (hitPoint – start).magnitude, and return true.

    4. If no hit, restore startCollider, set distance = maxLength, return false.

  • Usage:


Usage Scenarios & Tips

  1. Quick Range Checks

    • Use MaxRange(speed, gravity, height) to decide if a target is out of theoretical range before attempting a more expensive solution.

  2. Single‐Frame Aim

    • For a turret that does not account for target motion:

  3. Moving Target Intercept

    • To lead a moving enemy, call the 3D “moving target” solver:

  4. Trajectory Visualization

    • To draw a predictive line or spawn tracer particles along the path:

  5. Planned Bounce Calculations

    • Combine SphereCast(...) with Ballistics.Solution(...) for successive bounces:

    • Append path1 to path0 if you wish to visualize or feed into a “follow‐path” component.

  6. Custom Gravity or Other Constant Forces

    • Any method that takes constantAcceleration (Vector3/Vector2) can simulate wind, buoyancy, or magnetic forces by changing constantAcceleration from (0, –9.81f, 0) to something else (e.g., (2f, –5f, 0)).

  7. Prescribed Apex Height

    • When you want a projectile’s highest point to be at a specific Y, use the arc‐ceiling solvers. This is especially useful for:

      • Curved arrow shots over cover.

      • Jump arcs for AI characters (treat them as “projectiles”).

  8. Fixed Flight Time

    • If you need the projectile to take exactly t seconds to reach the target (e.g., synchronized explosion), use Solution(start, target, gravity, flightTime).

  9. Error Handling

    • Always check return booleans or solution counts. If a solver returns false or 0, either the target is out of range, the angle/speed combination is impossible, or parameters are invalid (e.g., zero speed or zero gravity).

Last updated