Experience the most authentic and accurate bullet and projectile physics simulation with Ballistics. Whether you're developing a first-person shooter or a realistic military training simulator, our comprehensive solution has got you covered.
With Ballistics, you can accurately predict the trajectory of your bullets and projectiles. This feature allows you to plan your shots with precision, enhancing the realism and immersion of your virtual world.
Realism is key, and with Ballistics, you can incorporate the effect of bullet drop into your simulations. Witness the true-to-life behavior of bullets as they travel through the air, adjusting their trajectory over distance, just like in the real world.
Realistic Environmental Conditions
Take your simulations to the next level by replicating various environmental conditions. Ballistics enables you to simulate factors such as wind speed, wind direction, and other environmental elements that can influence the flight path of your bullets.
Our advanced physics engine includes accurate air resistance calculations. This means that your projectiles will experience the drag effect caused by the air, resulting in more lifelike movement and behavior.
Kinetic Energy System
Ballistics features a robust kinetic energy system, allowing you to accurately calculate and visualize the energy transferred by bullets upon impact. Immerse your users in a world where the laws of physics are faithfully represented.
We understand the value of your time, which is why Ballistics offers a user-friendly and straightforward setup process. Get up and running quickly, so you can focus on creating exceptional experiences.
Reusable Projectile Settings, Environmental Conditions, and Simulation Configs: Save time and effort with Ballistics' reusable settings and configurations. Once you've fine-tuned your projectile settings or environmental conditions, you can easily reuse them in other projects, streamlining your development process.
Even with thousands of bullets flying simultaneously, Ballistics remains highly performant. Our optimized engine ensures that you can achieve exceptional realism without compromising on speed or frame rates.
Incorporate Ballistics into your Unity projects today and elevate your bullet and projectile physics simulations to new heights. Experience unparalleled realism, enhanced gameplay mechanics, and create virtual worlds that leave a lasting impact. Take control of your simulations with Ballistics, the ultimate solution for realistic physics-based experiences.
Frequently Asked Questions
Everything you need to know about this asset.
No FAQs found yet.
Still have questions? Ask in our Discord.
How do I get started with Ballistics?
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.
Major Data Types
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.
What is Prediction vs. Simulation?
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.
protected IEnumerator Simulate();
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:
- protected System.Action<BallisticsHitData> onBallisticsComplete;
- protected System.Action<Kinematics> onBallisticsUpdate;
- protected ProjectileSO projectileSO;
- protected EnvironmentSO environmentSO;
- protected SimulationConfigSO simulationStateSO;
- public Projectile Projectile;
- public Environment Environment;
- public SimulationConfig SimulationConfig;
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.
Can you walk me through a first setup?
- Create a new empty Game Object. Call it Bullet.
- Create a script and attach it to your Bullet. Call this script BulletManager.
- Write a using declaration at the top of the script, using OccaSoftware.Ballistics.Runtime.
- Change the inheritance for BulletManager from MonoBehaviour to BallisticsProjectile.
- In your Start method, call the Projectile.SetPositionAndDirection(Vector3 position, Vector3 direction) method, passing in the transform.position and transform.forward for the Bullet game object.
- Create a new method, call it private void GetSimResults(BallisticsHitData ballisticsHitData).
- From the Start method, subscribe your GetSimResults method to the onBallisticsComplete callback by writing onBallisticsComplete += GetSimResults.
- Also, call your coroutine with StartCoroutine(Simulate());
- Finally, clean up after yourself in your GetSimResults method by unsubscribing from the callback and discarding the game object.
- You need to create Projectile, Environment, and SimulationConfig assets, and then drag and drop these assets into the corresponding fields in the Bullet inspector window.
- You can create these assets by right clicking in project window, then going to
- Create -> Ballistics -> Projectile,
- Create -> Ballistics -> Environment, and
- Create -> Ballistics -> SimulationConfig
What would a class using Ballistics look like?
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: