[Unity] Quaternion.LookRotation_예기치 않는 방향으로 회전하는 오류

지즈·2025년 2월 11일
0

Unity

목록 보기
11/17

우선 Quaternion.LookRotation 메소드에 대해서 알아야 한다.

Quaternion.LookRotation(Vector3 direction)

이 함수는 direction(벡터)를 회전값(쿼터니언)으로 변경한다.
즉, direction 이라는 방향 벡터가 월드에서는 어떤 회전값인지 알아낸다.
예를 들어 (1, 0, 0) 인 방향 벡터는 오른쪽을 가리키고 있고, LookRotation을 이용하면 월드에서 오른쪽을 바라보기 위한 회전값(rotation)을 얻을 수 있다.
이를 transform.rotation 등에 대입하면 월드에서 direction 방향을 바라보도록 회전할 수 있게 된다.

문제 상황

코드 목표 : 화면에서 클릭한 지점으로 플레이어가 이동할 때, 플레이어가 목표 지점을 바라보도록 회전시킨다.

// 방향 벡터 구하기
// _destPos : 화면에서 클릭한 땅 오브젝트의 월드 좌표 값
// direction : 목표 지점까지의 방향 벡터
Vector3 direction = _destPos - transform.position;

// Slerp() : 부드럽게 회전한다.
// LookRotation(directino) : 방향 dir을 바라보기 위한 rotation 값을 구한다.
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), 10 * Time.deltaTime);

이 코드를 사용하자 두 가지 문제가 발생했다.

1. 오브젝트가 x 축을 기준으로 회전하는 오류 발생 (앞뒤로 넘어짐)

고꾸라졌다. 위 코드에서 _destPos는 땅 오브젝트의 월드 좌표 값을 갖는다. 플레이어의 transform.position.y_destPos.y는 당연히 다른 값이므로, direction 방향 벡터에서 y값 또한 0이 아닌 값이 들어갔고 오류로 이어졌다. 바로 LookRotation()이 x 축을 기준으로 회전하도록 한 것이다. 고개를 고정한 채로 위아래로만 끄덕여보자. 당신 머리의 방향 벡터 y 값이 변하고 있는 것이다. 이 상태에서의 회전값을 구하고 적용하니, 당연히 오브젝트는 앞뒤로 넘어지게 된다.

(Constraints > Freeze Rotation을 사용하지 않는 이유는 전 포스팅에 작성했다. Freeze Rotation은 Rigidbody의 회전을 막는 것이고, Quaternion.LookRotation()은 transform의 회전을 다루는 것이라 원하는대로 회전하지 않게 된다.)



direction.y = 0;
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), 10 * Time.deltaTime);

direction의 y값을 0으로 수정하니 해결됐다. 그런데 또 다른 문제가 발생했다.

2. 회전이 끝나고 미세하게 예기치 못한 방향으로 더 회전한다.

원하는 방향으로 회전했지만, 마지막에 지 혼자 조금 더 회전하는 오류가 발생했다.
원인은 간단했는데, direction이 (0, 0, 0)이 되는 순간에 Quaternion이 "비정의된 상태"에서 자동으로 대체 회전을 결정하려고 하기 때문이었다. (0, 0, 0) 이라는 방향 벡터는 존재하지 않는다.

if (direction.x != 0 && direction.z != 0)
    transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), 10 * Time.deltaTime);

간단하게 조건문으로 체크해줬다.

다시 실행하니 아무런 문제 없이 동작하였다.

-끝-

profile
클라이언트 개발자가 되는 그 날까지 킵 고잉

0개의 댓글