큐브를 이리저리 (구의 범위 안에서) 돌려보며 플레이하는 게임을 만들고자 했다.
처음에는 큐브를 돌리는 것이 목적이기에 큐브를 돌리자!라는 생각을 했다.
하지만 유니티에서는 부모 오브젝트가 변경되면 자식도 변경되기에 큐브 안에 수억 개의 큐브가 존재한다면 큐브를 돌리는 것이 비효율적인 것이다.
카메라맨과 산이라고 생각해 보면 된다.
산을 돌리는 것이 효율적일까? 카메라맨이 뛰는 것이 효율적일까?
물론 경우에 따라 다를 것이다.
동굴 속에 존재하는 자그마한 산이라면 포크레인을 가져와서라도 산을 돌리는 것이 효율적일 수 있다.
앞으로 일어날 일, 이미 정해진 사항 등을 고려해서 선택해 주는 것이 좋다.
내 경우는 카메라맨이 수고해 주는 것이 낫다고 판단했다.
원의 범위에서 회전한 위치를 알려면 1개의 각도와 반지름만 가지고 있어도 된다.
각도를 기준으로 삼각 함수를 활용해 주면 해당 위치의 2차원 차원 데카르트 좌표를 알 수 있다.
그렇다면 구에서의 회전한 좌표는 어떻게 구할까?
출처 : https://w.wiki/8HbM
구 위의 좌표는 반지름과 2개의 각도를 가지고 있으면 된다.
3차원 데카르트 좌표계로의 변환은 공식을 활용해 주면 된다.
유니티에서는 y가 높이라는 점을 유의하여 코드를 작성해 주면 된다.
만약 특정 물체를 기준으로 구면좌표계를 구하겠다면 특정 물체의 중심 좌표에다가 구면좌표계를 변환한 데카르트 좌표를 그대로 더해주면 된다. (원점을 기준으로 구한 값이기에 그대로 옮겨서 적용해 주는 느낌이다)
InputSystem으로 작업하고 있다. 이동 방향에 대한 정규화된 벡터를 구해내서 각도에 더해주면 된다. 추가로 속도를 곱하여 조절해 줄 수 있다.
Deg2Rad를 곱해주고 있는데 각도에 대한 값을 degree를 radian으로 변경해 주는 것이다.
radian은 0부터 3.141592...의 값이기에 1의 값은 꽤 크다. 정규화된 벡터를 degree로 사용하고 변환하는 것이 통제하기에는 더 쉬울 것이다.
입력과 관련한 내용은 프로젝트마다 다르기에 여기선 넘어가겠다.
입력을 통해 방향을 구해준 뒤 Update에서 구면좌표계에 더해준다.
이후 구면좌표계를 3차원 데카르트 좌표계의 좌표로 변환하여 적용해 주면 된다.
테스트 결과 원하는 대로 구 위에서 이동을 한다.
하지만 한 가지 문제가 있다.
큐브를 바라보지 않는다는 것이다.
그럴 땐 LookRotation을 활용해 주면 된다.
그런데 또 한 가지 문제가 발생했다. 구면에 위, 아래를 지나가려 하면 Y 각도가 180도를 도는 것이다.
출처 : https://docs.unity3d.com/ScriptReference/Quaternion.LookRotation.html
LookRotation은 위의 기준을 2번째 인자로 받는다. 기본값으로는 Vector3.up을 사용한다.
구면에 위, 아래를 지나는 순간 위와 아래가 바뀌는 것을 막기 위해 회전을 해준 것으로 판단된다.
프로젝트마다 다르겠지만 내 프로젝트에선 한 바퀴를 도는 건 이상한 것 같아서 값에 제한을 두었다.
더 이상 구면에 위, 아래를 지나갈 수 없다.