Make a realistic bullets in Unity with C#

Add realism

In this section we will add factors that will affect the bullet, such as wind and drag.

Part 1. Wind

What you need to know if you are going to add realism to the bullet in Heun's method is to calculate the acceleration or velocity with the correct time. Gravity was a constant acceleration and isn't dependent on velocity or position, so we didn't need to care about it when we added gravity. If the wind is constant, we can just add it in the same way as we added gravity. So just uncomment the line "velocityFactor += new Vector3(2f, 0f, 3f);" where the vector is whatever wind you want.

//Heun's method - one iteration
//Will give a better result than Euler forward, but will not match Unity's physics engine
//so the bullets also have to use Heuns method
public static void Heuns(
	float h,
	Vector3 currentPosition,
	Vector3 currentVelocity,
	out Vector3 newPosition,
	out Vector3 newVelocity)
{
	//Init acceleration
	//Gravity
	Vector3 acceleartionFactorEuler = Physics.gravity;
	Vector3 acceleartionFactorHeun = Physics.gravity;


	//Init velocity
	//Current velocity
	Vector3 velocityFactor = currentVelocity;
	//Wind velocity
	velocityFactor += new Vector3(2f, 0f, 3f);


	//
	//Main algorithm
	//
	//Euler forward
	Vector3 pos_E = currentPosition + h * velocityFactor;

	//acceleartionFactorEuler += BulletPhysics.CalculateDrag(currentVelocity);

	Vector3 vel_E = currentVelocity + h * acceleartionFactorEuler;


	//Heuns method
	Vector3 pos_H = currentPosition + h * 0.5f * (velocityFactor + vel_E);

	//acceleartionFactorHeun += BulletPhysics.CalculateDrag(vel_E);

	Vector3 vel_H = currentVelocity + h * 0.5f * (acceleartionFactorEuler + acceleartionFactorHeun);


	newPosition = pos_H;
	newVelocity = vel_H;
}

Part 2. Drag

Drag force is more complicated to add compared with the wind, because the drag is dependent of the bullet's velocity. So we have to calculate the acceleration from drag 2 times.

//Heun's method - one iteration
//Will give a better result than Euler forward, but will not match Unity's physics engine
//so the bullets also have to use Heuns method
public static void Heuns(
	float h,
	Vector3 currentPosition,
	Vector3 currentVelocity,
	out Vector3 newPosition,
	out Vector3 newVelocity)
{
	//Init acceleration
	//Gravity
	Vector3 acceleartionFactorEuler = Physics.gravity;
	Vector3 acceleartionFactorHeun = Physics.gravity;


	//Init velocity
	//Current velocity
	Vector3 velocityFactor = currentVelocity;
	//Wind velocity
	velocityFactor += new Vector3(2f, 0f, 3f);


	//
	//Main algorithm
	//
	//Euler forward
	Vector3 pos_E = currentPosition + h * velocityFactor;

	acceleartionFactorEuler += BulletPhysics.CalculateDrag(currentVelocity);

	Vector3 vel_E = currentVelocity + h * acceleartionFactorEuler;


	//Heuns method
	Vector3 pos_H = currentPosition + h * 0.5f * (velocityFactor + vel_E);

	acceleartionFactorHeun += BulletPhysics.CalculateDrag(vel_E);

	Vector3 vel_H = currentVelocity + h * 0.5f * (acceleartionFactorEuler + acceleartionFactorHeun);


	newPosition = pos_H;
	newVelocity = vel_H;
}

You should also create a new script called BulletPhysics where you can collect all methods that affect the bullets, and add a method that calculates drag. You should change these parameters, like mass and area, to fit your bullet.

using UnityEngine;
using System.Collections;

public class BulletPhysics : MonoBehaviour 
{
    //Calculate the bullet's drag's acceleration
    public static Vector3 CalculateDrag(Vector3 velocityVec)
    {
        //F_drag = k * v^2 = m * a
        //k = 0.5 * C_d * rho * A 

        float m = 0.2f; // kg
        float C_d = 0.5f;
        float A = Mathf.PI * 0.05f * 0.05f; // m^2
        float rho = 1.225f; // kg/m3

        float k = 0.5f * C_d * rho * A;

        float vSqr = velocityVec.sqrMagnitude;

        float aDrag = (k * vSqr) / m;

        //Has to be in a direction opposite of the bullet's velocity vector
        Vector3 dragVec = aDrag * velocityVec.normalized * -1f;

        return dragVec;
    }
}

That's all of the external factors we are going to add for now. If you press play you will notice that the bullets are no longer hitting the target. The equation we used to calculate the angle is not working if we add drag and wind.

How the bullet misses the target if we add wind and drag