Ballistic Trajectory in Unity3D

Luis Riera
5 min readFeb 17, 2024
Source: U.S. Air Force via Washington Business Journal

In order to model the physics for simulating a ballistic trajectory, we will require a few tools from physics and math. The tools are equations that will help us rearrange variables so we end up with other useful equations or mathematical expressions. These equations will help us calculate the required velocity to hit a target at a landing position from a launch position.

At the end, we will implement these equations using C#, inside Unity3D’s game engine to simulate the ballistic trajectory of an object.

We begin by introducing the 3 kinematic equations used throughout this exercise.

We also introduce the quadratic formula which will be helpful when solving one of the equations shortly. (Note: the x seen in the equation below is not related to the x in the diagram above. This x is just a general abstraction for the quadratic equation).

Rearranging Eq. 1 to resemble the quadratic formula pattern

Plug the coefficients into the quadratic equation 4) with t in place of x:

Simplify,

Here, we have found the time to hit the ground, given initial y-velocity, initial y-position, final y-position, and gravity. Only the positive case makes sense. We need to find relationships for the y-velocity, V_0y, that relate it to other variables we know — like max height or initial height.

Luckily, from Eq 2., we can solve for V_0y in terms of y_max and y_0. We are able to set V_fy = 0 because the final velocity at y_max is 0. This implies the change in height goes from y_0 to y_max:

Plug V_0y back into Eq. 5 and simplify

Given,

Then,

We now have the time required to pass through a given height, y_max, final height, y_f, and an initial height, y_0.

Given these constraints, we can solve for V_0x using Eq. 2

If y_f is 0, or the target location is on the ground:

And previously,

This tells us the velocity required to travel a distance x in a given time, t (in terms of initial height, final height, and max height).

In other words, given g, the time of flight is dependent on:
1. how high the object will travel
2. at what height it began, and
3. at what height it will land

We have eliminated the dependency of time on initial y-velocities.

That concludes our mini-exploration of kinematic equations and applying algebraic manipulation to come up with some useful expressions. These mathematical expressions can be used in a game engine like Unity3D to simulate, or model, the ballistic like trajectory of an object like a basketball, soccer ball, or other projectile in a video game. We will only need to input a few parameters — the heights and distance.

Thanks to our work, we can calculate the velocity in x and y-direction required to hit a land position, given:

max height : y_max
initial height: y_0
final height: y_f
gravity: g
horizontal distance to Land Position: x

Now, let’s implement this in C# for Unity3D!

The code is pretty self-explanatory, but if you would like some additional explanation — please reach out. Here is my LinkedIn.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LaunchControls : MonoBehaviour
{
public GameObject projectile;
public GameObject launchSite;
public GameObject landingTarget;
public float yMax;
private float g; // gravity
private float y_0;
private float x;
private float z;

void Start()
{
// Set parameters that will determine time of flight and velocities required for launch
g = 9.8f;
y_0 = projectile.transform.position.y - landingTarget.transform.position.y;
x = landingTarget.transform.position.x - launchSite.transform.position.x;
z = landingTarget.transform.position.z - launchSite.transform.position.z;
}

void Update()
{
// If left-mouse button is clicked, launch projectile
if (Input.GetMouseButtonDown(0))
{
LaunchBall(projectile);
}
}

void LaunchBall(GameObject launchObject)
{
// Launch projectile using rigid body
Rigidbody projectileBody = launchObject.GetComponent<Rigidbody>();
projectileBody.velocity = CalculateVelocity();

}

Vector3 CalculateVelocity()
{
// Distance X and Z to target location
Vector3 displacementXZ = new Vector3(x, 0, z);

// Implement equations derived from kinematic analysis
Vector3 velocityY = Vector3.up*Mathf.Sqrt(2*g*(yMax - y_0));
Vector3 velocityXZ = displacementXZ/(Mathf.Sqrt(2*(yMax - y_0)/g) + Mathf.Sqrt(2*yMax/g));

Vector3 velocity = velocityXZ + velocityY;
return velocity;
}

}

Here we can see what the result looks like in Unity:

You can move the target location to launch the projectile in different directions. You can also adjust the maximum height of the projectile by changing Y Max in the inspector. Magic!

--

--