Built-In Render Pipeline
High Definition Render Pipeline
Universal Render Pipeline
Simulate realistic projectile physics for any projectile ballistics including handguns, rifles, tank shells, and air force projectiles.
Ballistics is your one-stop-shop for realistic bullet and projectile physics simulation.
This page serves as a quick start reference document regarding os.Ballistics - a physics-based bullet ballistics system for Unity.
os.Ballistics is organized into three namespaces:
[.c]Runtime[.c] is the primary namespace that you will interact with. You can reference the Demo namespace to understand usage patterns. You likely won’t need to interact with the Editor namespace.
os.Ballistics also includes three primary classes of data that you will want to familiarize yourself with:
Projectiles, Environment, and SimulationConfigs can all be created as Scriptable Object assets by designers ahead of time, or they can be created or modified in code during gameplay.
Projectile describes a ballistics projectile, including characteristics such as Origin, Direction, Muzzle Velocity, Initial Kinetic Energy, Mass, etc. When you instantiate a projectile, you will likely want to call Projectile.SetOriginAndDirection(Vector3 origin, Vector3 direction) to initialize these fields before passing along to the simulation. Some of these characteristics are calculated automatically (e.g., Initial Kinetic Energy), but most are expected as inputs.
Environment describes a set of Environment Conditions, including characteristics such as Gravity, Atmospheric Pressure, Humidity, Temperature, Air Density, etc. Some of these characteristics are calculated automatically (e.g., Air Density), and others are expected as inputs (e.g., Humidity, Temperature)
SimulationConfig describes the nature of the simulation that should be executed, including characteristics such as Maximum Simulation Distance and Simulation Timestep.
Runtime contains one public static method you may want to interact with:
[.c]public BallisticsPrediction BallisticsCore.Predict(Projectile projectile, Environment environment, SimulationConfig simulationConfig);[.c]
Usage: When called, this method will execute an instantaneous simulation of the projectile and return back a BallisticsPrediction. Expect BallisticsPrediction to return null if the Prediction was unable to run. If the BallisticsPrediction is not null, you can check the BallisticsPrediction.BallisticsHitData.DidHit boolean to understand whether the ballistics system determined that a collision would occur. Expect BallisticsPrediction.HitInfo to be populated only when DidHit is true.
The BallisticsCore.Predict method should generally be called by the artillery piece itself rather than the projectile. It can be used to estimate approximate point of impact or to draw trajectories before actually shooting. Note that the prediction is calculated using the physics simulation in place at the time of the prediction. However, the bullet would take real time to travel, but the global physics simulation is not interpolated forward in any way.
What does this mean? In short, you cannot use the BallisticsCore.Predict method to determine whether a moving enemy would be hit along this trajectory in the future.
You will also want to set particular Game Objects as BallisticsProjectiles. You will use class inheritance for this. On your bullet prefab, open your primary handling script. Change the inheritance from MonoBehaviour to BallisticsProjectile.
The BallisticsProjectile base class includes the Simulate(); method, which is the realtime version of the BallisticsCore.Predict() method mentioned above. You want to iniherit from BallisticsProjectile and call the Simulate(); method for projectiles that should have join the realtime ballistics simulation.
Simulate uses fields in the BallisticsProjectile class to execute the simulation. Explore the BallisticsProjectile base class to understand these fields in more detail. At a high level, these are:
Generally, the Projectile, Environment, and SimulationConfig will be automatically set based on the Scriptable Objects set in the inspector for the projectileSO, environmentSO, and simulationSO fields. However, you can manually override these values with runtime ones by simply setting them.
Simulate runs as a Coroutine. Data from this coroutine can be passed back via callbacks to methods using the onBallisticsUpdate and onBallisticsComplete actions.
onBallisticsUpdate will trigger a callback every execution of the coroutine except for the final one.
onBallisticsComplete will trigger a callback on the final frame of execution of the coroutine.
When instantiated, the bullet’s transform will follow the path of the simulated trajectory and will write a debug log when it hits a collider in the path. See this gist for an example: