Unity

Unity Quaternion과 Euler

KJaebee 2022. 6. 21. 11:52

유니티에서 오브젝트의 회전을 보다 잘 이해하고 다루기 위해서 Quaternion과 Euler에 대해 알아야할 필요가 있다.

먼저 Euler Angle이란 x, y, z 각 각의 축을 기준으로 360도 회전하는 좌표계이다.

직관적이고 간단해서 비교적 어렵진 않지만 Euler Angle은 짐벌락(Gimbal Rock)이라는 문제점을 가지고 있다. 짐벌락이란 회전축은 필연적으로 두 개의 축이 회전중에 겹쳐지는 현상이 발생하는데 그렇게 되면 회전축 하나가 사라지게 되면서 사라진 회전축으로 회전이 불가능하게 되는 현상을 말한다.

왼쪽부터.. 회전 축이 사라지는 모습

이러한 현상이 생기는 이유는 오일러 앵글이 자체적으로 설정되어있는 순서로 해당 축들을 개별적으로 계산하기 때문이다. Unity에서는 오일러 앵글이 x, y, z 순서로 계산된다.

세 개의 축을 동시에 계산하지 않고 각 축을 독립적으로 판단하기에 겹쳐지게 되는 현상이 발생하는 것이다. 그리고 이렇게 축이 겹쳐버리면 어느 한 축에 대해서는 계산이 불가능하기에, 정확한 각도 계산이 불가능하다.

Unity로 2D 게임을 제작할 때에는 문제가 없지만 3D 게임 같은 경우에는 구현에 한계가 있다.

이것을 보완하기 위해 탄생한것이 바로 'Quaternion' 쿼터니언이다. 쿼터니언은 각 축을 한꺼번에 계산하기 때문에 짐벌락 문제가 발생하지 않는다. Euler Angle과는 다르게 쿼터니언은 4개의 성분 x, y, z, w 으로 이루어져 있다. 때문에 쿼터니언은 내부가 수학적으로 복잡하게 구현되어 있어 이를 제대로 이해하지 못한다면 다루기 상당히 까다롭다.

쿼터니언은 방향(Orientation) 과 회전(Rotation) 둘 다 표현할 수 있다. 하지만 한 방향에서 다른 방향으로 측정하기에 180 보다 큰 값을 표현할 수 없다는 단점이 있다.

이 점이 쿼터니언을 직관적으로 이해할 수 없는 큰 이유 중 하나이다. 꾸준히 공부하도록 하자.

쿼터니언은 다루기 어려우니 일단 Unity에서 만든 함수를 사용하는걸 권장한다.

Quaternion.Euler

public static Quaternion Euler(float x, float y, float z)

Quaternion.Euler 함수를 통해서 오일러각을 쿼터니언으로 변경시켜 사용한다. 해당 함수 인자에 오일러각을 넣으면 쿼터니언으로 변환된 값을 반환시켜준다.

Euler함수를 사용해서 오브젝트를 회전시켜봄.

Quaternion.Euler함수를 이용한 코드
wasd를 누르면 회전한다.

Quaternion.LookRotation

public static Quaternion LookRotation(Vector3 forward, Vector3 upwards = Vector3.up)

첫 번째 인자에 방향벡터를 입력하면 자기 위치를 기준으로 해당 방향 벡터를 바라본다.

주로 타겟을 바라보게 할 때 사용하는 함수이다.

LookRotation 함수를 사용해서 목표를 바라보게 만듬
target이 움직이는 방향으로 바라본다

Quaternion.Slerp

public static Quaternion Slerp(Quaternion.a,Quaternion.b, float t)

form과 to 사이를 t로 구형보간 한다.

이 함수는 투 쿼터니언의 중간 값을 리턴 시켜준다. Slerp 함수를 사용할 때 종종 t 값에 대해 헷갈리는 경우가 있는데,

Slerp 함수는 lerp 함수에서 쓰이는 선형보간법이 아닌 구면선형보간법 기반으로 되어있다는 점을 명심하자.

Lerp함수와 Slerp 함수는 세 번째 인자에 따른 반환 값이 다르다.

Slerp를 사용하고 싶다면 선형보간법과 구면선형보간법의 차이를 숙지해야 원하는 각도 변환을 연출 할 수 있을 것이다.

Lerp와 Slerp의 차이.

초록점에서 빨간점으로 이동할 때 Lerp는 직선으로 Slerp는 곡선으로 보간 된다.

-움짤

Quaternion.FormToRotation

public static Quaternion FormToRotation(Vector3 formDirection, Vector3 toDirection)

formDirection에서 toDirection으로 회전한 쿼터니언을 반환한다.

다음 함수를 적용해보았다.

transform.rotation = Quaternion.FormToRotation(Vector3.up, Vector3.right)

FormToRotation 함수를 적용시킨 큐브

Vector3.up에 있는 녹색 화살표가 Vector3.right 방향으로 z축이 회전한 모습이다.

회전시킬 중심 축을 첫번 째 인자로, 회전하고 싶은 방향벡터를 두 번째 인자로 넣어서 사용

'Unity' 카테고리의 다른 글

Unity 점프 구현하기  (0) 2022.06.21
Unity Input으로 오브젝트 이동 구현  (0) 2022.06.21