handakim25 / ProjectTitan

0 stars 0 forks source link

ProjectTitan

프로젝트 소개

간단한 3D RPG 게임 데모입니다. 신입 유니티 클라이언트 프로그래머로서, 기본적인 구현과 다양한 시도를 적용하여 제작했습니다. 던전을 클리어하고 몬스터를 처치하며 퀘스트를 수행해 보스를 처치하는 것을 목표로 하고 있습니다.

작업 환경

주요 기능

캐릭터 기능

캐릭터의 이동은 Character Controller를 이용해서 구현했습니다. InputSystem을 이용해서 콜백을 통해서 구현했고 입력과 카메라 방향에 맞춰서 이동을 하도록 했습니다. 이동 / 점프 / 공격 등의 상태를 가지게 되며, 이는 FSM 같은 형식으로 구현되어 있습니다. 각각의 상태에 맞춰서 Animation Conroller에 변수를 지정해줬고 이를 통해서 적절하게 움직임을 나타내도록 했습니다. 공격, 대시 같은 경우 애니메이션의 종료를 판단해야 되므로 Animation State Machine Behaviour를 이용해서 끝나는 순간 Callback을 호출해서 이를 알 수 있도록 했습니다.

공격의 경우 공격 가능 상태에서 공격 입력이 들어올 경우 공격 상태로 진입합니다. 트리거 기능을 통해서 Animation으로 진행이 되며 공격이 발생하는 순간 Physics OverlapBox를 이용해서 피격체를 검사합니다. 피격체의 경우는 LayerMask를 통해서 적합한 물체만을 판별하고 Health Component를 찾아서 TakeDamage를 호출합니다. 이러한 방식으로 각각의 Object가 자신의 피격 상황을 처리하게 됩니다.

아이템 기능

아이템 탐지 및 획득 기능

상호 작용한 객체를 찾는 것은 성능 상의 최적화를 위해서 0.1초의 주기를 가지고 탐지를 합니다. 미리 설정한 범위 내에서 Interaction Layer를 대상으로 탐지를 하며 없어진 물체와 추가된 물체를 찾아서 이를 Interaction List를 갱신합니다. 매 번 새로운 리스트를 생성하지 않는 이유는 Interaction UI에서 기존 객체의 경우 순서가 유지되고 커서의 상태가 유지되어야 하기 때문입니다. 상호작용 가능한 물체가 존재할 경우 상호작용 UI가 활성화되고 이 때 상호작용 가능한 UI 입력을 받으면 상호 작용을 선택하고 상호 작용을 실행할 수 있습니다.

인벤토리 구현

아이템과 상호작용하게 되면 인벤토리에 아이템을 추가하게 됩니다. 인벤토리 UI가 활성화되면 인벤토리의 모든 아이템의 슬롯을 생성해서 스크롤뷰에 추가합니다. 그리고 선택된 카테고리에 맞춰서 해당 되는 유형의 아이템만 활성화시키고 나머지 슬롯은 비활성화를 통해서 필터의 기능을 구현했습니다. 각 슬롯은 EventTrigger를 이용해서 구현이 되어 있으며, Run-Time 시에 필요한 트리거만 등록하고 Callback을 등록합니다. 아이템 사용 버튼을 클릭하면 아이템을 착용하거나, 제거하게 되고 이에 따라서 현재 선택된 슬롯을 다시 찾습니다. 기본적으로 다음의 슬롯을 선택하게 되고 다음 슬롯이 없을 경우 이전 슬롯을 선택하게 됩니다.

대화 시스템

다이얼로그 에디터는 그래프 형태로 제작하게 되었고 이는 UI Toolkit의 GraphView 기능을 통해서 구현했습니다. 각각의 대화, 선택지를 노드 형태로 표현할 수 있고 이를 연결해서 하나의 대화 흐름을 구성할 수 있도록 했습니다. 또한, 조건 노드를 추가해서 특정 조건이 성립했을 경우에만 표시되도록 구현했습니다. 이러한 Grpah 형태의 데이터는 다시 JSON 형태로 옮겨지고 해당 데이터를 읽어서 Run-Time에서 활용할 수 있게 했습니다.

각각의 노드는 ID를 가지고 있고 다음 노드의 ID를 가지고 있어서 다음 노드로 진행될 수가 있습니다. 만약에 다음 노드가 없을 경우 대화 종료 노드를 의미합니다. 각각의 노드에도 퀘스트를 트리거하거나 아니면 특정 조건을 트리거할 수 있도록 했습니다. 퀘스트 트리거는 퀘스트 수락을 위해서 사용되고 퀘스트 클리어를 트리거할 수 있습니다. 또한, 게임 이벤트 변수를 트리거하게 해서 문이 열릴 수 있도록 하거나 할 수 있도록 했습니다.

대화 UI

다이얼로그 UI가 활성화되면 플레이어의 UI의 입력은 중지하고 다이얼로그 UI만 입력 받을 수 있도록 했습니다. 각각의 대사는 일정한 주기마다 출력되도록 했는데 이는 코루틴을 통해서 구현했습니다. 만약에 클릭 입력을 받을 경우, 모든 대사를 출력하도록 했고 이미 출력된 상태일 경우 다음 대사로 넘어갈 수 있도록 했습니다. 다만, 선택지가 있는 대사일 경우 선택지를 출력하고 선택지 입력을 기다립니다. 오토 기능도 존재하며 오토 기능의 경우 모든 대사를 출력하고 일정 시간이 지나면 다음 대사로 넘어갈 수 있도록 했습니다. 대사를 너무 빨리 클릭해서 실수로 넘어가지 않도록 다음 대사가 출력되고 일정 시간은 모든 대사 출력 기능을 받지 않는 기능을 구현했습니다.

퀘스트 시스템

퀘스트 시스템의 경우 Event Bus를 이용해서 각각의 Event를 퀘스트 시스템이 구독하도록 했습니다. 이러한 구조는 몬스터의 처치 상황, 특정 이벤트 발생 등을 구독해서 퀘스트 시스템이 추적하기 위함입니다. 이러한 과정을 추적해서 퀘스트 클리어 가능 상태를 판단하고 퀘스트 NPC를 찾아가서 퀘스트를 클리어할 수 있도록 했습니다.

퀘스트 UI는 이러한 수락한 퀘스트의 리스트를 표현해 줍니다. 각각의 퀘스트를 ScrollRect에 슬롯을 추가하고 해당 슬롯을 선택할 경우 세부 사항을 확인할 수 있도록 했습니다.