오늘은 Score 표시, Game Over 처리, 메인메뉴 Scene, 난이도 조절 등의 작업을 진행했다.
Player가 Coin과 충돌할 경우 Score가 1씩 증가하게 했다.
이렇게 증가한 값을 GameManager와 HUDManager를 싱글턴 패턴으로 사용하여 화면 HUD에 실시간으로 Update되게 했다.

Coin을 먹을 경우 왼쪽 상단에 값이 1씩 증가한다.
Player가 Obstacle(Spike Plate, Arrow)에 충돌할 경우 Game Over 처리를 해주었다.

위 Panel을 HUDManager에서 관리하다가 Player가 Obstacle과 충돌하면 HUDManager를 호출하여 Game Over Panel을 띄워준다.
이 때 Player의 Sprite를 누워있는 Sprite로 변경하고, 위쪽 방향으로 살짝 띄워 Game Over가 되었다는 것을 표현했다.

간단하게 게임 플레이 시 사용하던 Background와 캐릭터 Sprite를 사용하여 Menu Scene을 만들었다.

Player가 Coin을 20개 먹을 때마다 게임의 난이도를 상승시키는 기능을 추가했다.
게임의 속도를 증가시키는 방향으로 난이도를 상승시키려고 했는데 생각해보니 Background와 Object의 MoveSpeed는 [SerializeField]로 Inspector에서 직접 변경 및 관리하고 있었다.
따라서 게임 속도를 증가시키려면 MoveSpeed 값을 가진 모든 GameObject를 찾아서 값을 직접 변경시켜줘야 했다.
하지만, FindObjectsOfType로 해당 GameObject를 다 찾기도 너무 비효율적이고 Background와 Object의 Scripts 또한 달라서 그냥 GameManager에서 전체 Object의 MoveSpeed를 관리하는 방향으로 코드를 변경했다.


위 같은 enum 자료형을 만들어서 GameObject마다 자신의 Type을 설정해주었고, GameManager를 호출하여 자신에게 맞는 MoveSpeed를 return 받게 했다.
결론적으로 잘 작동되나 싶었으나 정말 생각지도 못한 곳에서 문제를 발견했다.
Coin을 20개 먹을 때마다 MoveSpeed 값이 바뀌면서 Background의 position이 갑자기 확 바뀌는 것이다.

위 영상을 살펴보면 Coin을 20개 먹자마자 Background가 확 바뀌는 것을 볼 수 있다.
왜 그런가 살펴봤더니, 이 게임 개발의 1일차 리뷰를 보면 Background를 Scroll할 때 Mathf.Repeat() 함수를 사용했었다.
newPosition = Mathf.Repeat(Time.time * moveSpeed, width) 이 코드를 사용하여 0 ~ width 사이의 값을 반복적으로 받아와 원래 Position - newPosition으로 Background를 이동시켰다.
지금 생각해보면 당연히 안 되는건데 저 코드를 작성할 당시에는 moveSpeed가 조금 증가하면 해당 증가분 만큼만 적용되어 newPosition 값이 설정될 줄 알았다.
하지만, moveSpeed가 조금이라도 바뀔 경우 큰 오차를 발생시켰다.
이를 해결하기 위해 고민하다가 생각난 방법이 프레임마다 이동해야하는 값을 누적시킨 값을 Mathf.Repeat()의 인자로 사용하는 방법이었다.
이렇게 하면 MoveSpeed 값이 바뀌더라도 프레임마다 이동해야하는 값이 변경되는 것이기 때문에 누적 값으로 보면 부드럽게 이동속도가 변화하는 효과를 줄 수 있었다.

해당 코드로 변경한 후 Background가 갑작스럽게 확 이동하는 현상은 고쳐졌다.

코인을 20개 먹을 때마다 게임의 속도가 빨라지고, 죽는 모션, Game Over Panel, Menu Scene이 잘 구현된 것을 볼 수 있다.
다음 번에는 Player가 날라오는 Obstacle을 패링하는 기능을 추가해봐야겠다.