Ballistic Path
A struct used in several of our tools: BallisticPath
represents the full flight trajectory of a projectile in Unity, sampling its position, velocity, and elapsed time at discrete “steps.” It also records its total flight distance and time, plus any collision (impact
) detected along the way. Designers and gameplay programmers can use it to preview trajectories, visualize flight arcs, or query where/when a projectile will be at any given moment.
Public Fields
(Vector3 position, Vector3 velocity, float time)[] steps
An ordered array of tuples, each containing:position
– World‐space position of the projectile at that sample.velocity
– World‐space velocity vector at that sample.time
– Elapsed time (since launch) when the sample was recorded.Use this array to iterate through the sampled trajectory for drawing gizmos, spawning effects, or debugging.
float flightDistance
The cumulative distance (in world units) traveled by the projectile along its path, up until impact or until it reached its maximum tracing length.float flightTime
The total time (in seconds) from launch until the projectile either collides or reaches the end of its traced path.RaycastHit? impact
A nullableRaycastHit
struct describing the collision point, normal, collider reference, etc.If
impact
isnull
, no collision occurred within the specified max length.If non‐null, you can read
impact.Value.point
,impact.Value.normal
,impact.Value.collider
, and so on.
Static Properties
static BallisticPath Empty
Returns aBallisticPath
with:steps
= an empty arrayflightDistance
= 0flightTime
= 0impact
=null
Use it when you need a default “no-fire” or “no-path” result.
Static Methods
Note for designers: Call
BallisticPath.Get(...)
from your C# scripts or via a debug gizmo to compute a full, sampled flight path before you actually fire the projectile.
Purpose Perform a “spherecast‐based” ballistic simulation, stepping the projectile from
start
with initialvelocity
and under Unity’s built-inPhysics.gravity
. At each increment (defined byresolution
), it checks for collisions againstcollisionLayers
.If a collision is detected, the returned path ends at that impact point and records the
RaycastHit
.Otherwise, it traces forward up to
maxLength
and returns the full sampled path (possibly withimpact = null
).
Parameters
start
(Vector3
): World‐space origin of the projectile.startCollider
(Collider
): The collider at launch (so that the algorithm can ignore immediate self-hits).velocity
(Vector3
): Initial world‐space velocity vector (including direction and speed).radius
(float
): Radius of the projectile’s “sphere” when sphere-casting. Use this if you want to approximate a projectile with a finite size.resolution
(float
): Distance step between samples. Smaller values yield more granular sampling but cost more CPU. For example,0.5f
means “step in 0.5-unit increments along the trajectory.”maxLength
(float
): Maximum ray-distance to trace before giving up (e.g., 100 m).collisionLayers
(LayerMask
): Layers to test for collision.queryTriggerInteraction
(QueryTriggerInteraction
, optional): Whether to include trigger colliders in detection (default:UseGlobal
).
Returns A
BallisticPath
instance whose fields are:steps[]
: Every sampled(position, velocity, time)
the simulator recorded until impact or until it ran out ofmaxLength
.flightDistance
: Total path length along those samples.flightTime
: Time at the final sample (i.e., steps[^1].time).impact
: If a collision happened, theRaycastHit
; otherwisenull
.
Typical Usage
Instance Methods
(Vector3 position, Vector3 velocity, float time) Lerp(float time)
Linearly interpolates between the two nearest sampled steps to return an approximate(position, velocity, time)
at the requestedtime
(seconds since launch).Purpose Designers use
Lerp(..)
when they want to know exactly where (and how fast) the projectile is at an arbitrary moment along its flight—without having to manually find and blend two samples.For example, you might spawn a trail effect or leave a decal at a specific elapsed time.
Parameter
time
(float
): The desired elapsed‐time point in seconds.If
time ≤ 0f
, returns the very first sample (steps[0]
).If
time ≥ flightTime
, returns the final sample (steps[^1]
).Otherwise, it finds the two adjacent samples whose
.time
bracket the requestedtime
, then returns a blended tuple.
Returns A tuple
(position, velocity, time)
:position
– The interpolated world‐space position at the requestedtime
.velocity
– The interpolated world‐space velocity at the requestedtime
.time
– The same inputtime
(clamped between 0 andflightTime
).
Typical Usage
Designer Tips
Sampling Granularity (
resolution
)Lower
resolution
values (e.g.,0.1f
) yield more accurate arcs but more array entries (more memory/CPU).Higher values (e.g.,
0.5f
or1.0f
) produce fewer samples but can miss fast, short collisions.
Collider Assignment (
startCollider
) Be sure to pass the same collider that your projectile will use at launch. That avoids immediately hitting yourself when the spherecast begins.Visual Debugging Since
steps[]
is just a list of(position, velocity, time)
, you can iterate it inOnDrawGizmos
or in a custom Editor script to render lines, spheres, or arrows showing the entire flight arc before firing.Checking for Hits
If
impact
is non‐null, you know exactly which point/normal the projectile will hit and whichCollider
it intersects.If it remains
null
andflightDistance ≥ maxLength
, the projectile simply continued beyond your specified length without impact.
Empty Path Use
BallisticPath.Empty
to initialize variables safely or to indicate “no trajectory yet.” For example:Then, after you fire or update, you assign it via
Get(...)
.
By using BallisticPath.Get(...)
and Lerp(...)
, designers can quickly compute, preview, and query full projectile trajectories—including sampling, collision detection, and interpolation—without writing manual raycasts or physics loops. This makes it easy to create aiming reticles, trajectory gizmos, and HUD indicators that respond accurately to gravity, speed, and scene geometry.
Last updated