TIL 25.05.05

조성원·2025년 5월 5일
post-thumbnail

미니게임 세부 설정 변경

GameManager와 UIManager

로비와 미니게임 씬을 만들고 GameManager와 UIManager를 로비에 넣고 모든 씬을 관리하게 하려고 했는데
문제는 미니게임 씬에 있는 오브젝트를 로비에 있는 Manager 인스펙터에 넣을 수가 없다.

2. 미니게임 내부에 FlapBirdGameManager를 별도로 만들고 상속해서 사용하기?

GameManager를 상속해봤자 그 씬에서 Instance로 접근할 수가 없었다.


3. GameManager에서 FindObjectOfType()으로 접근하기?

미니게임의 UI에서 UIManager를 빼고 다른 씬의 UIManager에서 FindObjectOfType로 찾으려고 해봤자 텅 빈 UI에서 어떤 컴포넌트를 기준으로 잡고 가져올 수 있을까...
가능하게 한다고 해도 엄청나게 지저분하고 불안정하고 시간도 많이 걸릴 것 같다.


생각 끝에 전체적으로 관리하는 GameManager을 하나 두고 미니게임에서 별도의 Manager를 만드는 게 가장 편하고 쉽고 안전한 방법인 것 같다는 결론을 내렸다.

로비에 GameManager, UIManager를 놓고 미니게임에는 별도의 Manager를 만들었다. 우선 전체적인 관리를 담당하는 실제 Manager들과의 구별을 쉽게 하기 위해 따로 인스턴스는 만들지 않기로 했다.



버그 발견

FlapBird의 점수 시스템은 Obstacles의 박스 콜리더에 닿았다가 벗어나면 점수를 얻는다(CollisionExit2D를 사용했기 때문에).

스크립트가 잘 작동하는지 확인하려고 플레이하던 중에 죽어서 떨어진 비행기가 장애물에 부딪히고 뒷쪽으로 굴러내려오자 1점이 추가되는 현상이 생겼다.

플레이어가 죽었을 때 따로 막을 수 있는 함수가 없어서 그런 듯하다.

return;을 넣어서 함수 실행을 막아야 할 것 같은데 어떤 기준으로 넣어야 할까?

플레이어 스크립트에 isDead 변수가 있었지만 private 처리해야 할 요소들이 있어서 함부로 public으로 만들 수도 없고, isDead 하나 public으로 만들자고 다른 멤버들을 하나하나 옮겨주자니 비효율적이었다.
그냥 Player의 isDead를 없애고 GameManager에 만들어서 Player에 붙이는 형태가 갖다쓰기도 편하고 위치를 혼동할 일도 없으니까 더 좋을 것 같다.

시작 전 설명 UI

우선 시작화면에서 클릭하기 전에 게임이 시작되지 않게 멈추는 기능을 만들어야 했다.
GameManager에 Time.timeScale을 통해서 캐릭터의 rigidBody와 velocity를 조절했다.

게임 시작을 GameManager에서 관리하므로 시작 전 설명 UI도 GameManager에서 나타나게 해야 할 것 같은데, UI는 UIManager에서 관리하고 있으니 어떻게 분할해야 할지 생각이 잘 나지 않았다.
휴일인 관계라 튜터님들께 여쭤볼 수도 없으니 우선은 GameManager에서 UIManager를 호출하는 방식으로 작동만 가능하게 해놓고 더 좋은 구조는 도전 기능을 만들면서 생각해봐야겠다.

필수기능 구현 끝

캐릭터 이동, 맵 설계 및 상호작용, 미니게임 실행 및 점수 표시, 게임 종료 및 복귀, 카메라 추적까지 구현했다.

미니게임을 로비와 연결하는 데에 생각보다 시간이 너무 오래 걸려서 완성이라고 하기는 많이 부족한 상황에서 그쳤다.

완성본 제출까지 거의 하루 남짓한 시간이 남았으니 도전기능을 하나라도 만들어야 할지 아니면 필수기능을 더 다듬을지 생각해봐야겠다.

끝이 아니었다

다 완성하자마자 새로운 문제가 나왔다.

최고점수 초기화용 버튼을 하나 만들었는데, 초기화는 제대로 되지만 누르면 게임이 바로 시작돼버린다.

원인 1. GameManager의 Update()에서 클릭 시 deltaTime = 1f;가 되게 했었는데 이게 문제일까?

=> Update를 없애고 따로 GameStart() 메서드를 만든 뒤 게임 시작 설명문을 버튼으로 만들어 달았다. 이건 원인이 아니었다.

원인 2. 실수로 어떤 버튼에 게임을 재시작하는 메서드를 잘못 연결했나?

=> 원망스럽게도 모두 훌륭하게 제자리를 지키고 있었다.

원인 3. 버튼이 문제가 아닌 것 같다. 어딜 클릭하든 다시 재시작이 된다.

=>

원인은 Player 스크립트에 있었다. isDead일 때 클릭이나 스페이스바를 누르면 재시작하게 만드는 함수.
강의를 보면서 따라 만든 거라 내가 이걸 썼다는 자각도 없었다.

RestartGame()을 없애면 이 자리에 뭘 해야 하나 머리가 핑 돌았지만 차분하게 생각해보니 의외로 쉽게 정리할 수 있었다.

버튼에 RestartGame을 대신 달아주면 진짜 끝.

profile
direction *= -1;

0개의 댓글