캐릭터를 모으고 성장시키기
숲 탐험을 클리어하면 기사 한 명을 얻고, 뽑기에서는 기사나 마법사를 얻도록 만듭니다. 같은 기사를 두 명 가지고 있어도 각각 성장시키고 파티에 넣을 수 있게 합니다.
1. 캐릭터 종류와 보유 공간 준비하기
Add features 에서 Characters 를 추가합니다. Tables → Characters 에서 다음 세 표를 편집합니다. 일반 셀은 선택 후 Enter를 누르고, 배열 셀은 더블 클릭해서 편집합니다.
| 표 | 행 | 입력할 내용 |
|---|---|---|
| 캐릭터 보유 공간(CharacterCollection) | Add row 클릭(ID 입력 불필요) | 초기 보유 공간 20, 최대 보유 공간 100 |
| 캐릭터 경험치(CharacterExperience) | Add row 클릭(ID 입력 불필요) | 필요 경험치 표에 1, 10, 20을 순서대로 추가. 초기 레벨 상한과 최대 레벨 상한은 모두 4 |
| 캐릭터(Character) | 행을 추가하고 ID를 knight로 설정 | 표시 순서 1 |
| 캐릭터(Character) | 행을 추가하고 ID를 mage로 설정 | 표시 순서 2 |
Publish → Calculate server differences 에서 배포한 다음 Update the Unity project 를 누릅니다. 보유 캐릭터는 Character, 경험치는 CharacterExperience 네임스페이스에 저장됩니다.
캐릭터 설정 템플릿을 다운로드합니다. 관리 콘솔의 Tokyo 리전에서 Deploy → Stack list → Create stack 을 엽니다. 이름을 adventure-characters로 지정하고 Template data 에서 다운로드한 파일을 선택한 뒤 생성합니다.
이 스택에는 보유 공간, 경험치, 뽑기, 파티 편성 설정이 들어 있습니다. 기존 adventure-game 스택은 그대로 사용합니다.
| 데이터 | 네임스페이스 | 설정 이름 |
|---|---|---|
| 보유 캐릭터 | adventure-character | Inventory Character, Item knight / mage |
| 경험치 | adventure-character-experience | Experience Experience |
| 캐릭터 뽑기 | adventure-character-gacha | Lottery normal, Showcase Showcase, 상품 normal |
| 파티 편성 | adventure-character-formation | Mold CharacterFormation, 저장 슬롯 0 |
초기 보유 공간은 20, 최대는 100이며 캐릭터 한 명당 스택 수는 1입니다. 같은 종류의 캐릭터를 여러 번 얻을 수 있도록 allowMultipleStacks를 true로 설정했습니다.
숲 클리어 보상에 기사 추가하기
Tables → Quests → Quest 의 forest에서 Completion rewards 를 엽니다. 코인, 미션 카운터, 회복약 액션은 그대로 두고 Add item → Not set 을 누릅니다. AcquireItemSetByUserId를 선택하고 다음 값을 입력합니다.
| 항목 | 값 |
|---|---|
| namespaceName | Character |
| userId | #{userId} |
| inventoryName | Character |
| itemName | knight |
| acquireCount | 1 |
저장한 뒤 서버에 배포합니다.
adventure-game의 현재 템플릿을 엽니다. main의 forest에서 contents → completeAcquireActions 끝에 다음 항목을 추가합니다. 기존 코인, 미션 카운터, 회복약 항목은 그대로 둡니다. 수정한 템플릿 전체로 스택을 업데이트합니다.
- action: Gs2Inventory:AcquireItemSetByUserId
request: |-
{"namespaceName":"adventure-character","userId":"#{userId}","inventoryName":"Character","itemName":"knight","acquireCount":1}Unity에 보유 캐릭터 표시하기
Unity의 재생을 멈추고 Extensions에서 Adventure Items 의 체크를 해제합니다. 왼쪽 모험 화면은 그대로 사용합니다.
AdventureCharacters.cs를 Assets/AdventureExtensions에 넣고 Extensions에 Adventure Characters 를 추가합니다. 로그인된 Gs2ClientHolder와 Gs2GameSessionHolder를 사용합니다.
AdventureCharacters.cs를 Assets/AdventureExtensions에 넣고 Extensions에 Adventure Characters 를 추가합니다. Login 에 씬의 AdventureLogin을 할당합니다.
재생한 뒤 왼쪽에서 숲 모험을 새로 시작하고 클리어합니다. 오른쪽 보유 목록에 knight와 개체를 구분하는 값이 표시됩니다. 숲을 한 번 더 클리어하면 knight가 두 행에 각각 나타납니다. 배포 후 보상 변경이 적용되기까지 최대 5분이 걸릴 수 있습니다. 기사가 늘지 않으면 잠시 기다린 뒤 숲 모험을 새로 시작해 클리어합니다.
처음에는 다음 호출로 목록을 가져오고, 이후에는 SubscribeItemSets()로 추가와 삭제를 전달받습니다. ItemName은 캐릭터 종류, ItemSetId는 개별 캐릭터를 식별하는 값입니다.
var inventory = Client.Inventory.Namespace(InventoryNamespace)
.Me(Session).Inventory("Character");
await foreach (var item in inventory.ItemSetsAsync())
{
if (item != null) owned.Add(item);
}2. 20코인으로 캐릭터 뽑기
Add features 에서 Character Gacha 를 추가합니다. Tables → Character Gacha 에서 다음 순서대로 행을 만듭니다.
| 표 | ID | 입력할 내용 |
|---|---|---|
| 희귀도(GachaRarity) | common | ID만 입력 |
| 뽑기(Gacha) | normal | 개최 일정은 비워 둠 |
| 희귀도 확률(GachaRarityRate) | 행 추가 | 대상 뽑기 normal, 희귀도 common, 추첨 가중치 1 |
| 캐릭터 확률(CharacterRate) | 행 추가 | 희귀도 common, 캐릭터 knight, 추첨 가중치 1 |
| 캐릭터 확률(CharacterRate) | 행 하나 더 추가 | 희귀도 common, 캐릭터 mage, 추첨 가중치 1 |
확률 표에서는 참조 대상을 선택하면 ID가 자동으로 정해집니다. ID 셀에는 입력하지 않습니다.
normal의 Cost per draw 를 열고 WithdrawByUserId 액션을 하나 추가합니다. namespaceName = Currency, userId = #{userId}, slot = 0, withdrawCount = 20, paidOnly = false로 설정합니다. 저장한 뒤 서버와 Unity 프로젝트에 반영합니다.
처음 배포한 characters.json의 LotteryMaster와 ShowcaseMaster에 이 설정이 들어 있습니다. 두 경품의 가중치는 모두 1이며, 상품은 20코인을 소비하고 획득 액션으로 Gs2Lottery:DrawByUserId를 실행합니다.
왼쪽 모험 화면에서 코인을 20개 이상 모은 뒤 오른쪽의 20코인으로 캐릭터 뽑기 를 누릅니다. 보유 목록에 기사나 마법사가 한 명 추가됩니다. 왼쪽 코인이 20개 줄었는지도 확인합니다.
구매에는 Showcase를 사용하고, 그 획득 액션에서 Lottery 뽑기를 실행합니다.
private async UniTask Draw(string requestId)
{
var transaction = await Client.Showcase.Namespace(GachaNamespace).Me(Session)
.Showcase("Showcase").DisplayItem("normal").BuyAsync(
1, speculativeExecute: false, duplicationAvoider: requestId);
if (transaction != null) await transaction.WaitAsync(all: true);
}3. 선택한 캐릭터에게 경험치 주기
강화에는 10코인 소비와 경험치 10 지급을 묶은 Exchange를 사용합니다.
Studio 캐릭터용 강화 설정을 다운로드합니다. 관리 콘솔에서 Deploy → Create stack 을 열고 이름을 adventure-character-training으로 지정합니다. Template data 에서 파일을 선택해 생성합니다. Studio가 만든 Currency와 CharacterExperience를 참조하는 설정입니다.
SDK 캐릭터용 강화 설정을 다운로드합니다. Deploy → Create stack 에서 이름을 adventure-character-training으로 지정하고 Template data 에서 파일을 선택해 생성합니다. adventure-coin과 adventure-character-experience를 참조합니다.
- 오른쪽 보유 목록에서 강화할 개체를 선택합니다.
- 선택한 개체의 경험치 읽기 를 누르고 현재 값을 확인합니다.
- 10코인으로 경험치 10 추가 를 누릅니다. 경험치 표시가 자동으로 갱신되며 10 증가합니다.
- 다른 개체를 선택해 경험치를 읽고, 그 개체의 경험치는 늘지 않았는지 확인합니다.
버튼을 누른 시점에 선택되어 있던 ItemSetId를 Train()에 전달합니다. 코드는 이 값에 :level을 붙여 경험치 저장 대상을 지정합니다. config의 값은 템플릿의 #{propertyId}에 들어갑니다.
private async UniTask Train(string itemSetId, string requestId)
{
var transaction = await Client.Exchange.Namespace("adventure-character-training").Me(Session).Exchange()
.ExchangeAsync("train", 1, config: new[] {
new Gs2.Unity.Gs2Exchange.Model.EzConfig { Key = "propertyId", Value = itemSetId + ":level" }
}, speculativeExecute: false, duplicationAvoider: requestId);
if (transaction != null) await transaction.WaitAsync(all: true);
}4. 세 칸의 파티 저장하기
Add features 에서 Party Formation 을 추가합니다. Tables → Party Formation 에 다음 값을 입력하고 서버와 Unity 프로젝트에 반영합니다.
| 표 | 행 | 입력할 내용 |
|---|---|---|
| 편성(CharacterFormation) | Add row 클릭(ID 입력 불필요) | 초기 저장 슬롯 1, 최대 저장 슬롯 1 |
| 편성 슬롯(CharacterFormationSlot) | slot1, slot2, slot3 행 추가 | 모든 행의 배치 조건 .* |
characters.json의 FormationMaster에는 세 칸이 설정되어 있습니다. CharacterFormation의 저장 슬롯 0을 사용합니다.
- 편성 불러오기 를 누른 뒤 목록에서 한 명을 선택하고 선택한 개체를 슬롯 1에 넣기 를 누릅니다.
- 다른 개체를 선택해 슬롯 2에 넣습니다. 세 명이 있다면 슬롯 3에도 넣습니다. 빈 슬롯이 있어도 저장할 수 있습니다.
- 편성 저장하기 를 누릅니다.
- 재생을 멈췄다가 다시 시작하고 같은 플레이어로 로그인한 뒤 편성 불러오기 를 누릅니다. 각 슬롯에 이전과 같은 개체 ID가 표시됩니다.
저장할 때는 Inventory의 GetItemWithSignatureAsync()로 소유를 증명하는 서명을 받아 Formation의 SetFormAsync()에 전달합니다. 코드에는 같은 개체를 두 슬롯에 넣었는지 확인하는 처리도 들어 있습니다.