com.heathen.ballistics provides projectile trajectory solving, prediction, aiming and path rendering for arcing or physics-driven projectiles in Unity. Version 6.0 adds wind and drag, Burst batch solving, optional Entities (DOTS) support and a set of new tools, and fixes a number of long-standing solver and aiming bugs.
Requirements #
- Unity 6000.0 or later.
- Game Framework 1.4.0 or later (Toolbox installs it for you). Ballistics uses it for System Log.
- Burst 1.8.0 and Mathematics 1.2.5, both resolved automatically as package dependencies.
- Optional: the Entities package for the Entities layer and Unity Physics for the Entities collision adapter (both tested on 1.4.6). These layers compile only when the package is installed.
- Ballistics Toolkit no longer depends on Toolkit for Unity Physics or on Verlet. It never used either.
What’s New in 6.0 #
Everything new is opt-in. Leaving wind and drag at their defaults gives the same physics as 5.x. If you are upgrading from 5.x, read the Upgrading from 5.x section below before you update, because tracing is now exact and a few results shift slightly.
New #
- Wind and drag in 3D and 2D, through a medium (wind, linear drag, quadratic drag) that works with launch solutions, path prediction, trick shots, the line renderer and the aim components.
- Burst batch solving: solve many launch problems, or advance many projectiles, in parallel jobs.
- Elevation limits on launch solutions, and aim components that choose the first arc inside their limits.
- Surface-aware bounce: a fixed restitution and tangential loss, or the hit collider’s physics material, with a minimum bounce speed.
- Homing projectiles (3D and 2D) that lead moving targets and turn at a limited rate, with gravity and drag support.
- Allocation-free tracers that take a physics scene and a list you own.
- A Firing Table window (Window, Heathen, Ballistics Firing Table) with CSV export.
- Trajectory line styles (solid, dotted, dashed, fade-out) and a landing reticle. Neither needs any project assets.
- Events: solution found and lost on the targeting components, shoot on the trick shots, planned impact on the path followers.
- Optional Entities (DOTS) support when the Entities package is installed, plus a preview Unity Physics collision adapter.
- XML documentation on every public type and member.
- Example scenes that work with the Input System package or the legacy Input Manager, and a setup check in every scene that tells you what is missing.
- Log output through System Log, with the categories
Ballistics.PathFollow,Ballistics.TrickShotandBallistics.Samples.
Changed #
- Path tracing follows the exact constant-acceleration path, tests each segment as a straight cast, and measures
maxLengthas arc distance everywhere. - The gravity argument of the speed-based, flight-time and fixed-angle solvers accepts either sign.
BallisticPathFollowandBallisticPathFollow2Draise aplannedImpactevent.OnCollisionEnteris no longer attempted in 3D, andOnCollisionEnter2Dis sent only when Simulate Collision 2D is on.SphereCastandCircleCastno longer enable or disable the collider you pass in.TrickShot.Shoot()andTrickShot2D.Shoot()always predict afresh from the current aim. In continuous mode the trick shot lines no longer updateprediction.MaxRangeuses the optimal launch angle for the launch height instead of always 45 degrees.- The example scenes import to a new path (
Samples/Ballistics Toolkit/6.0.0/Example Scenes) and the misspelt “Perdiction” scenes are renamed “Prediction”. Copies you already imported are not updated, so re-import to get the new ones.
Fixed #
- Moving-target solutions returned no solution in the common case.
PredictandBallisticPath.Getreported an impact when nothing was hit, so bounce previews drew extra segments in mid-air.BallisticAim2Dnever rotated its pivot, andBallisticsData2D.Aimaimed 90 degrees off and used 3D gravity.- The Editor froze when a resolution of 0 was passed to a tracer or set on a trick shot.
- 2D bounce prediction could not re-hit the surface it had just bounced from.
BallisticPath2D.Getreturned null steps,TrickShot.Predictthrew when called before Start, andTrickShotLine2DRun On Start had no effect.BallisticPathFollowdid not replay after being re-enabled, threw on an empty path, and skipped planned impacts when several segments passed in one frame.- The closed-form moving-target solver allocated on every call. A rare dropped quartic root and quadratic precision loss for very small coefficients are also fixed.
Removed #
- The dependency on Toolkit for Unity Physics.
Key components #
BallisticTargeting/BallisticTargeting2D: solves the launch velocity to hit a target point given gravity and, optionally, a desired arc height or time of flight. RaisesonSolutionFoundandonSolutionLost.BallisticAim/BallisticAim2D: continuous aim-assist style targeting. Picks the first arc inside its limits, preferring the low arc.BallisticPathFollow/BallisticPathFollow2D: moves an object along a precomputed ballistic path and raisesplannedImpactat the predicted hit.TrickShot/TrickShot2Dand theTrickShotConstantAcceleration/TrickShot2DConstantAccelerationvariants: predict and fire shots, including bounces, with anonShootevent.TrickShotLine/TrickShotLine2D: draws the predicted trick shot, with line styles and an optional landing reticle.BallisticPathLineRender: renders a projectile’s predicted path through aLineRenderer, useful for telegraphing throws and shots to the player. ExposesHasImpactandLastImpact.BallisticHomingProjectile/BallisticHomingProjectile2D: homing projectiles, see Homing projectiles below.
Wind and drag #
BallisticMedium (3D) and BallisticMedium2D (2D) are serializable structs with three settings: wind, linearDrag (in 1/s) and quadraticDrag (in 1/m). Drag is -(linear + quadratic * |v - wind|) * (v - wind). All zero is a vacuum and gives exactly the 5.x behaviour. BallisticMedium.FromPhysical builds a medium from air density, drag coefficient, area and mass. A 2D medium converts implicitly to 3D.
A medium field is available on TrickShot, TrickShot2D, BallisticPathLineRender, BallisticAim and BallisticAim2D. In code, Ballistics.Advance and Advance2D step a projectile (exact in a vacuum, RK4 otherwise), Ballistics.Simulate runs a full flight, and the Solution and Solution2D overloads that take a medium solve stationary targets (two arcs, optional flight times) and intercepts of moving targets. The tracers and BallisticsData.Aim, AimHigh and Predict have medium overloads too.
In the Editor, a two-arc solve with drag takes about 0.2 to 0.7 ms, and the low-arc solve the aim components use takes about 0.04 to 0.14 ms. These are Editor (Mono) measurements, not player builds. Wind is constant in space and time, and there is no spin or altitude-dependent air density.
Solving and aiming #
The static Ballistics solvers give launch solutions for stationary and moving targets, by speed, by flight time or by fixed angle, in 3D and 2D. Speed-based, flight-time and fixed-angle solvers take a gravity magnitude and ignore its sign. The arc-ceiling solvers return gravity as a positive magnitude acting downward.
Elevation limits are new: Ballistics.Elevation and LimitElevation, plus Solution and Solution2D overloads with minElevation and maxElevation, in vacuum and with a medium. BallisticAim and BallisticAim2D use the limits to pick the first arc that fits, and clamp only if neither arc does. BallisticAim still assumes downward acceleration when it splits the result into yaw and pitch, and its limits use world yaw.
Predicting and tracing #
Ballistics.Raycast, SphereCast, Raycast2D and CircleCast march along the exact constant-acceleration path and test each step as a straight chord. maxLength is arc length everywhere, resolution below 0.001 is raised to 0.001, and a step cap stops runaway loops. BallisticsData.Predict, BallisticPath.Get, TrickShot and BallisticPathLineRender are built on them. When nothing is hit, the result reports no impact (impact == null).
For per-frame use there are allocation-free overloads that take a PhysicsScene or PhysicsScene2D and a list you own, BallisticsData.PredictNonAlloc and its 2D twin, and TrickShot.PredictPreview and TrickShot2D.PredictPreview. BallisticPathLineRender and the trick shot lines no longer allocate per frame.
BallisticPath.steps is an array of tuples, which Unity does not serialize, so TrickShot.prediction does not show in the Inspector.
Bounce #
BallisticBounceMode selects how a bounce is resolved: Damping (the default, same as 5.x), Fixed or Material. Fixed uses restitution (default 0.6) and tangentialLoss (default 0.1). Material reads the hit collider’s physics material and falls back to restitution 0 and friction 0.6 in 3D (0.4 in 2D) when it has none. minBounceSpeed (default 0) sets a minimum bounce speed. The fields are on TrickShot, TrickShot2D and BallisticPathLineRender, and the maths is available in code as BallisticBounce.Reflect, ReflectWithFriction (Coulomb) and Resolve.
Homing projectiles #
BallisticHomingProjectile and BallisticHomingProjectile2D steer toward a target, leading it if it is moving, at a limited turn rate. Settings include target, velocity, turnRate, constantAcceleration, medium, hitRadius and lifetime, with an onEnd event and a Reached result. The steering maths is public as BallisticHoming.LeadPoint, Turn and Step.
Presentation #
BallisticLineStyle draws a path as solid, dotted, dashed or fading out. It generates its own textures, so it needs no assets. BallisticReticle is a procedural landing marker with Show, Hide and SetReachable. A reticle field is available on BallisticPathLineRender, TrickShotLine and TrickShotLine2D.
Events #
onSolutionFoundandonSolutionLostonBallisticTargetingandBallisticTargeting2D.onShoot, which carries the projectile, onTrickShotandTrickShot2D.plannedImpact, which carries aRaycastHitorRaycastHit2D, onBallisticPathFollowandBallisticPathFollow2D. It is raised from FixedUpdate.
Batch solving (Burst) #
BallisticSolveRequest and BallisticSolveResult describe a launch problem and its answer. BallisticBatch.ScheduleSolve and ScheduleAdvance schedule BallisticSolveJob and BallisticAdvanceJob to solve many problems, or step many projectiles, in parallel, with or without wind and drag. The managed solvers and the jobs share one internal core. In the Editor, 10,000 solves with drag took about 2.5 ms and 100,000 projectile steps about 0.19 ms. These are Editor measurements, not player builds.
Entities (DOTS) #
When the Entities package is installed, the Heathen.Ballistics.Entities assembly compiles automatically, in the namespace Heathen.UnityPhysics.Entities.
- Components:
BallisticBody,BallisticField(a singleton medium),BallisticFloor(a singleton floor),BallisticImpact(a buffer),BallisticActive,BallisticAimRequestandBallisticAimResult. - Systems:
BallisticAdvanceSystem(Burst, runs inFixedStepSimulationSystemGroup, one bounce per body per step) andBallisticAimSystem(Burst, parallel). BallisticLauncher.Launchto fire a body, and baking authoring inBallisticBodyAuthoring,BallisticFieldAuthoringandBallisticFloorAuthoring.BallisticCollisionModechooses between no collision, a floor and Unity Physics.
In the Editor, 100,000 bodies with wind and RK4 drag step in about 0.36 ms per fixed step, and 10,000 aim requests with drag solve in about 2.9 ms. The layer is tested on Entities 1.4.6.
Preview: with com.unity.physics also installed, the Heathen.Ballistics.Entities.Physics assembly adds BallisticPhysicsAdvanceSystem, BallisticPhysicsCast and BallisticPhysicsSettings, which collide bodies against a Unity Physics world and take restitution and friction from the hit physics material. This adapter is a preview. Its cast and stepping logic are tested, but the system itself has not been run in a full project, and bodies must not carry colliders that its own cast can hit.
Firing Table window #
Open Window, Heathen, Ballistics Firing Table. Enter a launch speed, gravity, launch and target height, a range step, and optionally wind and drag. The window lists the elevation and flight time for both arcs at each range, and Copy CSV and Save CSV export the table. The same data is available in code as BallisticFiringTable (Build and ToCsv).
Samples #
Import the Example Scenes sample from the Package Manager. It lands in Samples/Ballistics Toolkit/6.0.0/Example Scenes and contains four scenes: Fantasy Style Ballistic Simulation, a 3D and a 2D Prediction scene (bounce prediction), and a 3D Targeting Tool. The scenes work with the Input System package or the legacy Input Manager. Every scene has a setup check that covers the screen with what is wrong and how to fix it, and hides itself once everything passes. The 2D scene needs the 2D Sprite package (com.unity.2d.sprite), and its sprites do not draw without it.
There are no sample scenes for wind and drag, homing, bounce modes, batch jobs, line styles or Entities. Use the XML documentation on each type (shown in your IDE) for the exact members.
System Log #
Ballistics logs through System Log. The categories are Ballistics.PathFollow (BallisticPathFollow and BallisticPathFollow2D), Ballistics.TrickShot (TrickShot) and Ballistics.Samples (the sample setup check). Configure each destination under Project Settings, Subsystems, System Log. The matching log gates are Heathen.LogGates.Ballistics.PathFollow and Heathen.LogGates.Ballistics.TrickShot. The static solvers never log.
Upgrading from 5.x #
Go through this list before updating. Items 2 to 11 can change results in an existing project.
- Install Game Framework 1.4.0 or later. Toolbox does this once it offers 6.0. Ballistics will not compile without it.
- Tracers (
Raycast,SphereCast,Raycast2D,CircleCastand everything built on them):maxLengthis now arc length everywhere (5.x used straight-line distance for Raycast, SphereCast and Raycast2D).resolutionbelow 0.001 is raised to 0.001. Marching follows the exact path and tests each step as a chord, so path points, impact points, hit times anddistancediffer slightly from 5.x, and previewed paths may end at slightly different points.distancenow includes the final partial segment.startCollideris never modified: 3DSphereCastignores colliders it overlaps at the start, and 2DCircleCastignores it only within one radius of the start. BallisticPathFollowandBallisticPathFollow2D:invokeOnCollisionEnterno longer tries to sendOnCollisionEnterin 3D, which never delivered a message. Listen to the newplannedImpactUnityEvent instead. In 2D,OnCollisionEnter2Dis sent only whensimulateCollision2Dis on, and never with a nullCollision2D.TrickShot.Shoot()andTrickShot2D.Shoot()always predict afresh from the current aim. The continuous-mode lines draw fromPredictPreviewand no longer updateTrickShot.prediction, so readpredictiononly after callingPredict().TrickShotLine2D.continiousRunis renamedcontinuousRun. Serialized values are kept, but code references must be renamed.runOnStartnow works.- Speed-based, flight-time and fixed-angle solvers take a gravity magnitude and ignore its sign (a negative value used to return NaN or no solution). The arc-ceiling solvers return gravity as a positive magnitude acting downward. Earlier documentation said negative, the values are unchanged.
MaxRangeuses the optimal launch angle for the launch height, so values for a launch height above zero are higher.BallisticsData.PredictandBallisticPath.Getreport no impact (impact == null) when nothing is hit. 5.x always returned a non-null default hit.BallisticPath2D.Getreturns an emptystepsarray instead of null.- 2D aiming is corrected.
BallisticsData2D.AimandPredictdefault toPhysics2D.gravity, andAimandAimHighnow aim correctly (they were 90 degrees off).BallisticAim2Dnow rotates its pivot. - Moving-target solutions (
SolutionandSolution2Dwith a target velocity) now return solutions in the common case, which also benefitsBallisticAim.Aim(target, velocity). BallisticAimandBallisticAim2Dchoose the first arc inside their limits, preferring the low arc, and clamp only if neither arc fits. 5.x always used the low arc and clamped it.- The Example Scenes sample imports to
Samples/Ballistics Toolkit/6.0.0/Example Scenes, and the “Perdiction” scenes are renamed “Prediction”. Existing imported copies are not updated automatically. - Logging goes through System Log. There is no raw
Debug.Logoutput from runtime code, so existing Console filters for Ballistics messages will need to move to the System Log categories. BallisticPathFollow: re-enabling restarts playback, an empty path no longer throws, several segments passed in one frame no longer skip planned impacts, andvalidateBouncecasts honourcollisionMask.
Known limitations #
- Performance figures on this page are Editor (Mono, Burst) measurements. No player build, IL2CPP or other platform figures are published.
- Wind is constant in space and time. There is no spin and no altitude-dependent air density.
- The Entities Physics adapter is a preview, and the Entities layer is tested only on Entities and Unity Physics 1.4.6.
BallisticPath.stepsis not serialized by Unity, soTrickShot.predictiondoes not appear in the Inspector.