스파르타 내일배움캠프/Weekly I Learned

Weekly I Learned - 8th Week [Team Project:3D 게임 제작하기]

불면증 도사 2024. 11. 8. 19:58

금주에는 팀 프로젝트로 3D 게임 제작을 진행하였다.

선택지는 러너, 퍼즐, 생존 중 선택이었는데, 우리 팀은 퍼즐을 선택하였다.

[사실, 사전 투표에서는 생존이 우세였는데, 호러 컨셉이 나오자 마자 전원 만장일치로 퍼즐이 되었다.]

 

본인은 그 중 퍼즐 로직을 담당했다.

[이번에는 본인 파트에 관해서는 트러블 슈팅을 할 만 한 게 없었다. 아래 설명으로 모두 설명이 되다 보니...;;]

그럼, 본인이 작성한 것을 기반으로 한번 둘러보자.

 

[Project git URL: https://github.com/lsu0503/Puzzle_Horror_8_Team.git]

 

GitHub - lsu0503/Puzzle_Horror_8_Team: 공포 퍼즐게임

공포 퍼즐게임 . Contribute to lsu0503/Puzzle_Horror_8_Team development by creating an account on GitHub.

github.com

 

시연 영상(편집되어 있습니다.)

 

퍼즐 로직

[이해를 돕기 위해서, 해당 프로젝트의 발표 자료 중 일부를 활용하여 작성하겠다.]

본 게임의 모든 퍼즐 관련 클래스(2레벨 제외)는 PuzzleBase라는 부모 클래스를 상속받는 구성으로 되어있다.

 

그 PuzzleBase는 PuzzleSwitchCell이라는, 퍼즐의 상태를 담당하는 클래스를 가지고 있는데,

이는 PuzzleManager에도 Dictionary 형식으로 실려서 양쪽에서 공동 관리를 하게 된다.

[여담으로, 상기 다이어그램에서 화살표 2개 모두 잘못 기입되어 있다. 포함관계여야 하는데 연관관계로 표시해 버렸다...]

 

퍼즐의 On/Off 처리는 PuzzleBase에서 본인의 PuzzleSwitchCell을 통해서 진행되며, PuzzleManager는 해당 퍼즐에 영향을 받는 장해물이 퍼즐과 연동하기 위한 중계점으로 활용된다.

 

위에서 보이듯, Puzzle Switch Cell은 switchEvent라는 event를 지니고 있는데, 이 switchEvent에 각 장해물의 활성화 함수를 할당하는 방식으로 구성되어 있다.

이를 위한 할당은 targetKey라는 KeyContainer구조체 배열으로 구성되어 있는데, 이는 인스펙터에서 2차원 배열이나 List<array>를 지원하지 않기 때문에 저렇게 만든 것이다.

[추후 커스텀 인스펙터에 대해서 공부해야 할 거 같다.]

 

퍼즐의 완성 판정은 퍼즐의 상태를 확인하는 PuzzleReactor를 상속받는 ObstacleController에서 수행한다.

PuzzleReactor를 부모 클래스로 분리한 이유는  본문에는 작성하지 않았지만, PuzzleReactor에 따라서 PuzzleBase를 비활성화 하는 PuzzleActivator 클래스도 있기 때문이다.

[PuzzleActivator 자체는 정상 동작함을 확인했는데, 현재 Level3에서는 동작하지 않는다. 이유를 찾아봐야 할 거 같다.]

이 ObstacleController에 존재하는 event(상단 자료 참고)에 장해물의 동작을 담당하는 클래스들이 장해물 동작 함수를 할당하는 형식을 이용, 퍼즐 조건이 만족되면 활성화되고, 만족된 상태가 해제되면 비활성화 되는 구조로 되어있다.

 

이러한 구조를 통해서 독자적인 형태를 지닌 Level2를 제외한 모든 퍼즐이 일관적으로 처리되도록 구성되어 있다.

[아무래도 Level1, Level2, Level3 모두 제작자가 다르다 보니 통일시키지 못했었다.]

※ 본인은 Level3의 퍼즐 파트를 담당하였다.