In this article(Unity 2D – Arrow Physics) I’m going to show you how to create a realistic movement for a 2D arrow in Unity. I’m already assuming that you know how to work with Unity so I will skip the obvious steps.
I will start but telling you how to setup your arrow like a game component. After that I will show you how your C# script should look like.
Step 1 – Rigidbody 2D
Make sure that you have a Rigidbody 2D component on your unity game object. Your Rigidbody should look like this:
By using a dynamic body type we are able to physically simulate the behavior of the game object . Also, by having a gravity scale equal to 1, we will simulate the object movement in an environment with a gravity acceleration of 9.80665 m/s2.
You can find more about how Rigidbody 2D works in the Unity manual: RB2D
Step 2 – C# Script
In order to obtain the behavior that we wanted we also need to attach a script to our game object.
using UnityEngine;
public class Arrow : MonoBehaviour
{
[SerializeField]
private Vector3 m_target;
private Rigidbody2D m_rb;
private float m_TimeInTheAir = 1.5f;
void Start()
{
m_rb = GetComponent<Rigidbody2D>();
m_rb.velocity = CalculateVelocity(m_target, m_TimeInTheAir);
}
void Update()
{
UpdateAngle();
}
Vector2 CalculateVelocity(Vector3 target, float time)
{
Vector3 distance = target - this.transform.position;
float distanceX = distance.x;
float distanceY = distance.y;
float Vx = distanceX / time;
float Vy = distanceY / time + (0.5f * Mathf.Abs(Physics.gravity.y) * time);
return new Vector2(Vx, Vy);
}
void UpdateAngle()
{
float angle = Mathf.Atan2(m_rb.velocity.y, m_rb.velocity.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
}
}
Actually we are only applying simple physics:
1. Velocity equation: velocity = distance / time
2. Velocity after a certain time of acceleration: velocity = initial velocity + acceleration * time
We only need to calculate velocity once, so we are going to do this inside the Start method. The CalculateVelocity method is, as I said, respecting the velocity equations and returning a Vector2 with the X and Y velocity which will be used by the Rigidbody component.
In the Update method we are only going to call the UpdateAngle method in order to make sure that the game object will always rotate to follow the velocity evolution,