수평 방향(X축)으로 일정한 속도(Vx)로 운동하면서 수직 방향(Y축)으로 중력의 영향을 받는 경우, 시간(t)에 따른 위치(x, y)는 다음과 같이 표현된다.
x = Vx * t
y = Vy * t - (1/2) * g * t^2
여기서,
Vx는 초기 속도에서의 수평 방향 성분이다.
Vy는 초기 속도에서의 수직 방향 성분이다.
g는 중력 가속도다.
포물선 운동의 각도(firingAngle)를 알고 있다면, 초기 속도 V와 각 성분 Vx, Vy는 다음과 같이 구할 수 있다.
Vx = V * cos(firingAngle)
Vy = V * sin(firingAngle)
따라서, 투사체를 던질 때 필요한 초기 속도 V는 목표물까지의 거리와 각도에 의해 결정된다. 이 코드에서는 projectile_Velocity 변수를 사용하여 초기 속도를 계산한다.
float projectile_Velocity = target_Distance / (Mathf.Sin(2 * firingAngle * Mathf.Deg2Rad) / gravity);
여기서,
target_Distance는 투사체와 목표물 사이의 거리다.
firingAngle은 투사체를 던질 각도다.
gravity는 중력 가속도다.
위 공식을 통한 나의 예시 코드이다.
/// <summary>
/// 포물선 코드
/// </summary>
/// <returns></returns>
IEnumerator ParabolicProjection()
{
// 투사체를 물체를 던지는 위치로 이동하고 필요한 경우 offset을 추가합니다.
Projectile.position = myTransform.position + offset;
// 대상까지의 거리 계산
float target_Distance = Vector3.Distance(Projectile.position, target);
// 물체를 지정된 각도로 목표물에 던지는 데 필요한 속도를 계산합니다.
float projectile_Velocity = target_Distance / (Mathf.Sin(2 * firingAngle * Mathf.Deg2Rad) / gravity);
// 속도의 X,Y 추출
float Vx = Mathf.Sqrt(projectile_Velocity) * Mathf.Cos(firingAngle * Mathf.Deg2Rad);
float Vy = Mathf.Sqrt(projectile_Velocity) * Mathf.Sin(firingAngle * Mathf.Deg2Rad);
// 비행 시간을 계산한다
float flight_Duration = target_Distance / Vx;
// 발사체를 회전 시켜 목표물을 향하게 한다
Projectile.rotation = Quaternion.LookRotation(target - Projectile.position);
//경과 시간
float elapse_time = 0;
Vector3 defaultScale = Projectile.localScale;
//투사체가 목표 지점 까지 포물선을 그리면서 정해진 시간과 속도 만큼 간다는 주석
while (elapse_time < flight_Duration)
{
Projectile.localScale = Vector3.Lerp(defaultScale, maxScale, elapse_time / flight_Duration);
Projectile.Translate(0, (Vy - (gravity * elapse_time)) * Time.deltaTime, Vx * Time.deltaTime);
elapse_time += Time.deltaTime;
yield return null;
}
DestroyObject();
}