오늘 한 것: 위성 공전·자전 프로토타입
원탭 캐주얼 게임을 하나 개인 프로젝트로 시작했습니다. 이름은 Catch-Star. 완성될지 어떨지도 모르겠지만, 만드는 동안 뭘 했는지는 남겨두는 게 나중에 도움이 될 것 같아서(본인 기준) 이렇게 기록을 시작합니다. 잘 정리된 강의 같은 글이 아니라 그날 작업 일지에 가깝습니다.
거두절미하고 본론으로. 오늘은 위성이 행성 주위를 도는 공전과 위성 자체가 제자리에서 도는 자전을 붙였습니다. 프로젝트 골격을 처음 올린 날이라 이것저것 딸려 들어갔지만, 실제로 손으로 친 건 스크립트 두 개가 전부다.
 - 1/body-0.gif)
돌려보면 이렇게 나옵니다. 그런데 화면에 잡히는 위성은 3기 중 1기뿐입니다. 궤도 중심을 (0, -3)으로 박아둬서 나머지 둘은 카메라 밖에 있다.
공전은 cos/sin으로 좌표를 직접 찍었다
Transform.RotateAround나 빈 부모 오브젝트를 회전시키는 방법 대신 Mathf.Cos/Mathf.Sin으로 매 프레임 좌표를 새로 계산했습니다. 이유는 하나인데, 지금 몇 도째인지와 반경을 코드가 직접 들고 있는 편이 나중에 편할 것 같아서입니다(본인 기준). 빈 부모 회전 방식은 부모 스케일이 균일하지 않으면 자식이 찌그러질 수 있다고 해서 일단 미뤄뒀다.
 - 1/body-1.png)
좌표를 찍는 부분은 이게 전부입니다.
offset += addOffset;
float radian = offset * Mathf.Deg2Rad;
float x = Mathf.Cos(radian) * DISTANCE;
float y = Mathf.Sin(radian) * DISTANCE - 3f;
satellite.transform.position = new Vector3(x, y, 0f);
각도를 offset에 계속 더하고 Mathf.Deg2Rad로 라디안으로 바꿔서 좌표를 찍습니다. 배치는 시작 각도를 한 번만 뽑고 거기에 120도씩 더하는 식이다.
float offset = Random.Range(0f, 360f);
for (int i = 0; i < 3; i++)
{
m_data[i].satellite = SpawnSatellite();
m_data[i].offset = (offset + i * 120f);
}
그래서 실행할 때마다 시작 방향은 다른데 간격은 항상 같습니다.
 - 1/body-2.png)
자전은 위성이 각자 돈다
자전은 링이 아니라 위성 본인(Satellite.cs)이 맡습니다. 링은 위치만 계산하고 위성은 자기 z축 회전만 담당하는 식으로 나눴습니다. 둘 다 초당 10도로 값은 같지만 인스펙터에서 따로 조절할 수 있어서 이렇게 두는 게 편했다.
this.transform.localEulerAngles = new Vector3(0,0, m_angle);
m_angle += Time.deltaTime * m_speed;
if (m_angle > 360f) m_angle %= 360f;
스프라이트는 Satellite_0~Satellite_6 7종 중 하나를 아틀라스에서 랜덤으로 뽑아 씌웁니다. SpriteAtlas.GetSprite는 부를 때마다 스프라이트를 새로 복제해서 돌려주기 때문에 매 프레임 호출하면 안 되는데, 지금은 Start에서 한 번만 부르고 있어서 괜찮습니다.
다음에 할 것
지금은 값을 코드에 박아둔 상태라, 하드코딩한 것들부터 인스펙터로 빼고 궤도 중심을 행성 트랜스폼 기준으로 잡을 생각입니다. 그다음이 게임다운 부분(별을 잡는 조작)이 될 것 같다.
참고 소스