Transform에는 특정 target을 바라보도록 하는 함수인 LookAt이 기본적으로 내장되어 있습니다. 그런데 이 함수는 한 프레임 만에 회전값을 변경시킵니다. 2D에서는 다음과 같이 간단하게 수식 하나로, 바라보는 방향 벡터의 x축을 기준으로 하는 각도(θ)값을 얻고 이를 통해 Quaternion.Lerp를 활용하여 부드럽게 회전시킬 수 있습니다.
바로 코드부터 봅시다.
public static class LookAtExtension
{
public static void LookAt2DLerp(this Transform transform, Vector2 dir, float lerpPercent = 0.05f)
{
float rotationZ = Mathf.Acos(dir.x / dir.magnitude)
* 180 / Mathf.PI
* Mathf.Sign(dir.y);
transform.rotation = Quaternion.Lerp(
transform.rotation,
Quaternion.Euler(0,0,rotationZ),
lerpPercent
);
}
}
위와 같이 확장메서드를 작성하면 다음과 같은 방식으로 어떤 MonoBehaviour 오브젝트가 특정 트랜스폼을 바라보게 할 수 있습니다.
Transform target;
void Update()
{
Vector2 dir = target.position - this.transform.position;
this.transform.LookAtLerp(dir);
}
코드는 sprite가 xy평면 상에서 움직인다는 가정 하에 작성되었으며, 기본적으로 0º일 때 <1, 0> 방향을 바라보고 있습니다. 식을 도출한 과정은 다음과 같습니다.
v1 = x축 방향 단위 벡터 = <1, 0>
v2 = 바라보는 방향 벡터 dir = <x, y> 라고 합시다.
두 벡터의 내적 v1•v2 = |v1| * |v2| * cosθ
= <1, 0>•<x, y> = 1*x + 0*y = x,
|v1| = 1이므로, x = |v2| * cosθ
→ cosθ = x / |v2|
∴ θ = acos(x / |v2|) = rotationZ
→ 라디안 값을 0~360 범위로 바꾸기 위해 (180 / pi) 를 곱하고, y가 음수이면 세타값도 음수로 바꾸어야 하므로 Sign(y)를 곱합니다.
(Sign은 삼각함수인 사인(sin) 함수가 아니라, 음수면 -1, 양수면 1을 반환하는 함수입니다.)
'Unity • C#' 카테고리의 다른 글
[Unity] DOTS: Jobs, Burst, ECS 간단 정리 (0) | 2023.06.19 |
---|---|
[Unity] IAP 구매버튼 Custom Editor로 편하게 만들기 (0) | 2023.05.21 |
[Unity] 편리한 데이터 관리 - Data Scriptable Object (0) | 2023.04.21 |
[Unity] PlayerPrefs - 암호화 및 임의 객체 저장 (0) | 2023.04.21 |
[Unity] UnityMediation.h file not found (2) | 2022.09.30 |
댓글