Rotate는 Object의 회전을 나타내는 요소로 Transform Component를 다룰 때 잠깐 설명했었다.
Transform Component에서 Rotate의 접근방법에 대해서 설명했는데 transform.rotate
변수로 직접 수정이 가능하다고만 설명하였다.
그렇다면, 3D모델에서 Rotate는 Vector3로 수정하면 되는가? 아니다.
transform.rotate
은 Quaternion
이라는 특이한 자료형을 가지고 있다. Quaternion
은 3차원 벡터가 아닌 4차원 벡터로 나타낼 수 있는 자료형으로 x,y,z,w로 나타낸다. x,y,z는 이미 알고 있는 회전축을 의미하고 w는 회전 각도를 나타내는 스칼라 값이다.
x,y,z값으로 회전을 표현하기 위해 transform.eulerAngles
를 사용하면 된다. Vector3로 얼마 만큼 회전할지를 나타낼 수 있다.
tranform.eulerAngles = new Vector3(0.0f, Time.deltaTime * speed, 0.0f);
위 코드는 매 프레임마다 speed에 해당하는 값 만큼 y축을 기준으로 회전한 방향을 바라보는 코드이다.
+=
같은 연산보다는 =
와 같은 대입연산을 추천한다는 의미이다.Delta에 해당하는 값으로 회전을 하고싶을 때는 transform.Rotate()
를 사용한다. Rotate 함수는 여러 오버로딩을 지원하지만 기본적인 사용방법은 Delta에 해당하는 값을 Vector로 넘겨주어 매 프레임마다 회전하는 값을 지정해줄 수 있다.
절대 회전은
transform.eulerAngles
, 증감 회전은transform.Rotate()
캐릭터가 이동을 할 때, 이동하고자 하는 방향을 바라보는 것은 거의 당연한 일이다. 어느 방향을 바라본다는 것은 기존 방향을 기준으로 특정 각도만큼 회전하는 것을 의미한다. 하지만, '무엇을 기준으로 하는지', '어디를 기준으로 하는지'에 따라 구현하는 내용이 다르다.
예를 들면,
WASD 이동
은 카메가라 바라보는 방향을 기준으로 입력된 방향을 바라봐야한다.마우스 클릭 이동
은 현재 위치 기준으로 지정된 좌표방향을 바라봐야한다.위 두개의 간단한 예시만 봐도 기준 방향
과 목표 방향
이 차이가 난다. 이를 구현하는 단계를 생각해보자.
회전하는 값
에 해당하는 스칼라 값이다.현재 바라보는 방향 벡터
와 바라봐야하는 방향 벡터
이다.두 벡터사이의 각도
를 알아낼 수 있다.각도를 알아내었으면 y축을 기준으로 회전하면 바라보고자 하는 방향을 바라볼 것이다. y축을 기준으로 하는 이유는 상황이 캐릭터가 평지에 서 있는 상황
으로 가정했기 때문이다.
만약 기울어진 평지라면,
수정->회전->수정
단계를 거치거나두 방향벡터에 동시에 수직관계에 있는 벡터
를 찾아 평면을 정의한 후 회전을 적용할 수 있다.transform.eulerAngles
을 이용한 회전은 짐벌락
이라는 현상이 발생할 수 있기 때문에 Quaternion을 이용한transform.rotate
를 사용한다.
짐벌락은 같은 방향으로 오브젝트의 두 회전축이 겹치는 현상을 의미한다.
두 축이 겹친다는 얘기가 잘 와닿지 않는다.
짐벌락 현상을 해결하기 위해 Quaternion을 사용한다고 하는데 Quaternion는 위에서 설명했듯이 x,y,z,w로 회전축과 방향을 동시에 가지는 요소이다.
Unity에는 euler를 Quaternion으로 변환하는 기능을 제공한다. 이를 이용해 transform.rotate
사용하는 방법은 아래와 같다.
transform.rotation = Quaternion.Euler(new Vector3(0.0f, 1.0f, 0.0f));
LookRotation은 원하는 방향을 바라보는 Quaternion을 만드는 함수이다. 여기서 Vector은 Local좌표가 아닌 World좌표계를 기준으로 방향을 계산한다.
transform.rotation = Quaternion.LookRotation(Vector3.forward);
Quaternion.LookRotation를 이용한 방향전환을 하면 값이 바로 바뀌어 방향이 뚝뚝 끊기는 느낌이다. 앞->왼쪽을 바라볼 때 바로 바뀌는 것이 아닌 천천히 돌도록 하고 싶을 때, Quaternion.Slerp()
를 사용한다.
transform.rotation = Quaternion.Slerp(transform.rotation,
Quaternion.LookRotation(Vector3.forward), 0.5f);
앞 2개의 인수는 Quaternion을 입력하며 fromQuaternion, toQuaternion를 의미한다. 세번째 인수는 비율을 나타내는데 1.0f에 가까울수록 from에서 to로 변하는 시간이 빨라진다.