퀘스트는 인게임에서 특정한 목표를 수행하고, 이에 대한 대가를 받는 컨텐츠입니다.
pc게임, 온라인 게임, 모바일 게임 등. 여러 종류의 게임에서 공통적으로 존재하는 것이기도 합니다.
모바일 rpg 게임을 구현한 배틀레드에서 이러한 퀘스트 시스템을 구현했습니다.
상단의 사진은 퀘스트 창의 UI를 표현한 창입니다.
일일, 주간, 일반, 전체 타입으로 나뉘어, 스크롤뷰가 정렬 Set되고 정렬값을 기준으로 퀘스트 데이터를 출력합니다.
스크롤뷰에 출력된 ui 오브젝트에는
좌측에 퀘스트 타입, 중앙에는 퀘스트 내용, 우측에 퀘스트 진행도를 나타내는 Progress바를 나타냈습니다.
만약 퀘스트의 조건을 만족했을 경우에는, 진행도 바의 색상이 가득 차게 되고, 클릭 시에 보상을 받을 수 있게 됩니다.
퀘스트에 대한 데이터를 저장하는 클래스를 새로 작성했습니다.
클래스의 맴버 변수는 '배틀블루 프로젝트' 때 작성했던 내용을 기본으로 하고, 추가적으로 필요한 변수를 생성하는 식으로 만들었습니다.
대표적으로 isQuestActive 변수가 있습니다.
퀘스트 활성 상태 체크용 변수로써, false 상태라면 퀘스트 창에 출력하지 않고 true일 경우에만 퀘스트 창에 출력하는 방식으로,
인게임 플레이 도중 추가되는 퀘스트를 구현할 수 있도록 했습니다.
ToDictionary() 함수는 퀘스트 클래스에 저장되어 있는 데이터를 파이어베이스에서 사용할 수 있는 데이터 형식으로 오브젝트화하는 함수입니다.
SetFromDictionary() 함수는 파이어베이스로부터 받은 Dictionary 오브젝트를 역직렬화하여, 퀘스트 클래스가 사용할 수 있는 데이터로 바꿔주는 Convertor 역할을 하는 함수입니다.
위 두 함수는
파이어 베이스 구현 문서에서 설명했던 것과 유사합니다.
파이어베이스에는 유저의 데이터 정보가 담겨있습니다.
인게임 재화, 아이템 리스트, 체력과 공격력 등등.
그렇기 때문에 퀘스트에 대한 정보 또한 파이어 베이스에 저장하도록 하였습니다.
Firebase에 저장된 데이터를 Load하여, 퀘스트 클래스 객체가 받아들일 수 있는 형태로 가공하는 함수입니다.
패턴 매칭 기능을 사용하여, 각각의 변수의 형식을 체크하고, 일치한다면 캐스팅하여 변수에 할당해줍니다.
그리고, 최종적으로 퀘스트 클래스에서 읽을 수 있는 객체 형식으로 만들어서, 전달하여 유저 데이터에 얕은 복사를 하여, DB 데이터를 이식해줍니다.
상단의 Load 함수와는 반대로 Save 역할을 해주는 함수입니다.
ToDictionary 함수를 통해서, 퀘스트 목록을 딕셔너리 배열로 변환하고,
파이어베이스에 딕셔너리 배열을 저장합니다.
퀘스트 매니저는 퀘스트의 데이터 관리, 진행 관리, 클리어 체크 및 보상 리턴, 일일/주간 퀘스트 초기화 등의 역할을 담당하는 매니저 클래스 입니다.
매니저 클래스인 만큼, 싱글턴 패턴을 상속받아서 전역에서 접근할 수 있도록 하였습니다.
퀘스트 매니저에서 필요한 구조체와 열거형 변수를 만들어 둡니다.
그리고, 위에서 언급한 기능을 처리하기 위해 필요한 데이터들을 딕셔너리로 매핑하여, 필요할 때마다 불러와서 사용할 수 있도록 했습니다.
기본적인 퀘스트 데이터 세팅 함수입니다.
즉 유저 클래스 객체의 QuestList 배열에 디폴트 퀘스트 데이터를 저장하는 함수입니다.
즉, 퀘스트 데이터의 값 변동 과정은 아래와 같습니다.
즉, 파이어베이스에 퀘스트 데이터가 없을 경우(초행 플레이어)를 대비하여, 디폴트 데이터를 설정해놓는 것입니다.
위 함수에서 초기화하는 값들은 퀘스트 매니저에서 사용되는 딕셔너리의 값들입니다.
퀘스트마다 가지고 있는 고유 id값(인덱스)에, 보상과 관련된 데이터를 매핑.
몬스터의 이름에, 진행도를 반영할 퀘스트의 인덱스 값을 매핑.
진행한 퀘스트의 이름(열거형)에, 진행도를 반영할 퀘스트의 인덱스 값을 매핑.
파이어 베이스에서 데이터를 받아와 유저 퀘스트 데이터를 수정한 이후에,
호출되는 함수입니다.
현재 시간과 퀘스트 클래스에 저장된 맴버 타임 함수 값을 비교하여 퀘스트 클래스의 내용을 초기화 해줍니다.
클리어 상태 체크는 UI매니저에서, 스크롤뷰 객체에 UI 오브젝트를 생성한 후, 각 오브젝트가 클릭되었을 때. 호출되는 함수입니다.
UI 오브젝트 객체를 맴버 변수로 받아서, 해당 객체가 가진 퀘스트 클래스의 데이터를 확인하여 퀘스트가 클리어 되었는지 체크하고,
클리어 가능하다면 보상 리턴 함수를 호출하고, UI 매니저의 하위 클래스인 퀘스트UI 클래스에, 내용출력 함수를 호출하여, 클리어 변화를 알립니다.
보상 처리 함수입니다.
UI 오브젝트 객체를 매개변수로 받아서, 매개변수에 저장된 맴버변수인 퀘스트 클래스 객체를 참조합니다.
퀘스트 클래스에 저장된 ID값을 기준으로 딕셔너리에 매핑되어 있는 보상 정보를 가져옵니다.
보상 정보는 태그, 보상 대상, 보상 갯수로 구성되어 있으며,
태그 - 보상 대상에 따라서 조건문으로 분기하여
UserClass 객체에 실제로 접근하여, 보상으로 얻을 데이터를 실제로 수정하여 반영합니다.
상단의 두 함수는
퀘스트 진행에 따라서, 수치를 변화하기 위한 함수입니다.
현재 퀘스트는
몬스터 킬에 따른 변화.
특정 동작(컨텐츠 종료) 완료에 따른 변화.
두 가지 방향으로 나뉘어 작성되었으며,
각각의 퀘스트 타입에 따라서, 딕셔너리에도 다른 데이터를 킷값으로 인덱스값을 매핑하고 있습니다.
몬스터 킬의 경우에는 사냥한 몬스터의 이름을 기준으로 하기 위한, name 값을 킷값으로.
특정 동작의 경우에는 동작을 열거형으로 저장하여, 킷값으로 사용합니다.
즉, 위 두 함수는 현재 구현된 퀘스트인,
몬스터 사냥(죽음 AI에 연결), 지하미궁 탈출(지하 미궁 기믹, 마지막 타일 도착 시 연결), 주사위 퍼즐(퍼즐 클리어 시 연결)에 적절히 함수를 호출받는 방식으로 퀘스트의 진행도를 수정하게 해주는 역할을 합니다.