매일 플레이할 이유 만들기
로그인한 날에 보상을 받고 모험을 세 번 클리어하면 추가 보상도 받도록 만듭니다. 지금까지 사용한 학습용 프로젝트와 계정으로 진행합니다.
1. 로그인 보너스 설정하기
1일 차에는 10코인, 2일 차에는 20코인, 3일 차에는 30코인을 지급합니다. 날짜는 일본 시간(JST, UTC+9) 자정에 바뀝니다. 접속하지 않은 날이 있어도 마지막으로 받은 보상 다음부터 이어서 받도록 합니다.
Add features 에서 Login Rewards 와 Missions 를 추가합니다.
Tables → Login Rewards → LoginRewardCollection 을 열고 다음 행을 만듭니다.
| 항목 | 입력할 값 |
|---|---|
| ID | daily |
| 진행 방식(mode) | streaming |
| 날짜 갱신 시각(resetHour) | 15(UTC 15시 = 일본 시간 자정) |
| 반복(repeat) | disabled |
| 놓친 보상 구제(missedReceiveRelief) | disabled |
LoginReward 에 day1, day2, day3 행을 추가하고 보너스 그룹을 모두 daily로 설정합니다.
각 행에서 Acquire actions → Add item → Not set 을 엽니다. 액션으로 DepositByUserId(money2), 대상 리소스로 None 을 선택합니다.
| 항목 | 입력할 값 |
|---|---|
| namespaceName | Currency |
| userId | #{userId} |
| slot | 0 |
depositTransactions 에 항목을 하나 추가합니다. price는 0, currency는 No value 로 설정합니다. count는 day1이 10, day2가 20, day3이 30입니다.
로그인 보너스와 미션 템플릿을 다운로드합니다.
- 관리 콘솔의 Tokyo 리전에서 Deploy → Stack list → Create stack 을 엽니다.
- 스택 이름을
adventure-daily로 지정하고 Template data 에서 다운로드한 JSON 파일을 선택한 뒤 생성합니다. - 상태가 Create complete 가 되면
adventure-login-reward와adventure-mission을 사용할 수 있습니다.
로그인 보너스 설정은 LoginRewardMaster → Properties → Settings → bonusModels에 있습니다.
| 항목 | 설정값 |
|---|---|
| name | daily |
| mode | streaming |
| resetHour | 15 |
| repeat | disabled |
| missedReceiveRelief | disabled |
| rewards | 10, 20, 30코인 입금 세 건을 이 순서대로 설정 |
이 스택은 로그인 보너스와 미션 설정만 추가합니다. 모험, 코인, 스태미나는 기존 adventure-game 스택을 사용합니다.
2. 모험을 세 번 클리어하는 미션 만들기
모험을 클리어할 때마다 1씩 증가하는 미션 카운터를 만듭니다. 세 번에 도달하면 버튼으로 30코인을 받을 수 있게 합니다.
Tables → Missions → MissionSetting 을 열고 Add row 를 누릅니다. 리셋 시각은 15, 주간 리셋 요일은 sunday, 월간 리셋 날짜는 1로 설정합니다.
다음 세 표에 행을 추가합니다.
| 표 | ID | 설정 |
|---|---|---|
| 미션 카운터(MissionCounter) | clear | ID만 입력 |
| 미션 그룹(MissionCollection) | adventure | 리셋 단위 notReset, 개최 일정은 비워 둠 |
| 미션(Mission) | clear3 | 미션 그룹 adventure, 진행 카운터 clear, 목표값 3 |
clear3의 Completion rewards 에 DepositByUserId(money2)를 추가합니다. 로그인 보너스와 동일하게 namespaceName = Currency, userId = #{userId}, slot = 0으로 설정합니다. depositTransactions의 price는 0, currency는 값 없음, count는 30입니다.
Tables → Quests → Quest 를 엽니다. forest와 cave의 Completion rewards 에 각각 다음 액션을 하나씩 추가합니다. 기존 코인 입금 액션은 그대로 둡니다.
| 항목 | 입력할 값 |
|---|---|
| 액션 | IncreaseCounterByUserId(mission) |
| 대상 리소스 | None |
| namespaceName | Mission |
| userId | #{userId} |
| counterName | clear |
| value | 1 |
저장하고 Publish → Calculate server differences 에서 배포한 뒤 Update the Unity project 를 실행합니다.
앞서 만든 adventure-daily에 다음 미션이 들어 있습니다.
| 설정 | 값 |
|---|---|
| 그룹 | adventure, 리셋 없음 |
| 카운터 | clear, 누적값 |
| 미션 | clear3, 목표값 3 |
| 보상 | adventure-coin의 슬롯 0에 30코인 |
adventure-game에 사용한 템플릿을 엽니다. forest와 cave의 contents → completeAcquireActions에 기존 입금 액션과 같은 깊이로 다음 항목을 추가합니다.
- action: Gs2Mission:IncreaseCounterByUserId
request: |-
{"namespaceName":"adventure-mission","userId":"#{userId}","counterName":"clear","value":1}Deploy → adventure-game → Update stack 을 열고 Template data 에서 수정한 파일을 선택해 업데이트합니다. Update complete 가 될 때까지 기다립니다. 이제 퀘스트 클리어 보상으로 코인 입금과 카운터 증가를 함께 실행할 수 있습니다.
3. Unity에 보상 받기 화면 추가하기
기존 모험 화면에 로그인 보너스와 미션 보상 버튼을 추가합니다. 화면 표시에는 계속 OnGUI()를 사용합니다.
Handler 추가하기
Unity의 재생을 멈추고 Hierarchy의 Gs2에 다음 컴포넌트를 추가합니다.
- Login Reward Collection Handler
- Mission Handler
- Mission Counter Handler
모험 화면에 보상 버튼 추가하기
- 이 장의 AdventureStudioView.cs를 다운로드해 기존
Assets/AdventureStudioView.cs를 교체합니다. Gs2의 Adventure Studio View 에서 새로 생긴 Login Reward, Mission, Counter 에 해당 Handler를 할당합니다. Mission Group 은adventure, Mission Name 은clear3으로 설정합니다.- 재생 후 로그인하면 스태미나 상점 아래에 보상 버튼과 진행 상황이 나타납니다.
기존 OnGUI()에서 추가한 DrawDailyRewards()를 호출합니다. 버튼을 눌렀을 때의 처리는 모험 시작·클리어와 같은 방식으로 작성합니다.
if (GUILayout.Button("오늘의 로그인 보너스 받기"))
Run(() => loginReward.Binder.Receive());
if (GUILayout.Button("미션 보상 30코인 받기"))
Run(() => mission.Binder.Receive());배포 코드에서는 로딩 중이나 처리 중에는 조작을 막고, 미션을 달성하면 보상 버튼을 누를 수 있게 합니다.
Binder 내부에서 트랜잭션 완료까지 기다리므로 화면에서 WaitAsync()를 호출할 필요가 없습니다. 표시할 때는 Handler의 Model을 참조합니다. 보상을 받거나 모험을 클리어해서 생긴 변경도 Handler에 반영됩니다.
재생 후 로그인하고 오늘의 로그인 보너스 받기 를 누릅니다. 1일 차가 ‘받음’으로 바뀌고 모험 화면의 코인이 10개 늘어납니다. 같은 날 다시 눌러도 코인은 늘지 않습니다.
다음으로 숲 탐험을 세 번 클리어합니다. 배포 후 카운터 추가가 적용되기까지 최대 5분이 걸릴 수 있습니다. 횟수가 늘지 않으면 잠시 기다린 뒤 숲 탐험을 새로 시작해 클리어합니다. 누적 클리어 횟수가 3이 되면 미션 보상 30코인 받기 를 누를 수 있습니다. 받으면 ‘받음’으로 바뀌고 일반 모험 보상에 더해 30코인을 얻습니다.
재생을 멈추고 빈 GameObject를 만들어 Extensions라고 이름 붙입니다. AdventureDaily.cs를 Assets/AdventureExtensions에 넣고 Extensions에 Adventure Daily 를 추가합니다. Login 에 씬의 AdventureLogin을 할당하고 Mission Group 은 adventure, Mission Name 은 clear3으로 설정합니다.
배포 코드의 Client는 GS2 클라이언트, Session은 로그인한 플레이어의 세션을 반환하는 프로퍼티입니다. 둘 다 AdventureLogin에서 가져옵니다.
보상 버튼은 RunWrite()를 통해 호출합니다. 여기서 요청에 키를 붙이고 ReceiveLogin()이나 ReceiveMission()의 requestId로 전달합니다. 통신 오류가 나면 같은 작업 재시도 로 동일한 요청을 보낼 수 있습니다. 8장과 마찬가지로 재생을 유지한 채 연결이 복구되면 바로 재시도합니다.
이 샘플은 OnGUI()로 모험 화면 오른쪽에 보상 버튼과 진행 상황을 표시합니다. Game 뷰를 넓혀 두 화면이 모두 보이게 한 뒤 재생하고 로그인합니다. 오늘의 로그인 보너스 받기 를 누르면 1일 차가 ‘받음’으로 바뀌고 왼쪽 코인이 10개 늘어납니다. 다시 눌러도 같은 날의 보상은 중복 지급되지 않습니다.
보상 수령 상태와 미션 진행 상황은 SubscribeWithInitialCallAsync()로 구독합니다. 모험을 클리어하거나 보상을 받으면 변경 알림에 따라 화면이 갱신됩니다.
날짜가 바뀌면 2일 차, 3일 차 순서로 받을 수 있습니다. 보상 수령에 사용하는 API는 다음과 같습니다.
private async UniTask ReceiveLogin(string requestId)
{
var transaction = await Client.LoginReward.Namespace(LoginNamespace).Me(Session).Bonus()
.ReceiveAsync("daily", speculativeExecute: false, duplicationAvoider: requestId);
if (transaction != null) await transaction.WaitAsync(all: true);
}다음으로 왼쪽 모험 화면에서 숲 탐험을 세 번 클리어합니다. 배포 후 카운터 추가가 적용되기까지 최대 5분이 걸릴 수 있습니다. 횟수가 늘지 않으면 잠시 기다린 뒤 숲 탐험을 새로 시작해 클리어합니다. 오른쪽 누적 횟수가 3이 되면 미션 보상 30코인 받기 를 누릅니다. ‘받음’으로 바뀌며 일반 모험 보상에 더해 왼쪽 코인이 30개 늘어납니다.
private async UniTask ReceiveMission(string mission, string requestId)
{
var transaction = await Client.Mission.Namespace(MissionNamespace).Me(Session).Complete(missionGroup)
.ReceiveRewardsAsync(mission, speculativeExecute: false, duplicationAvoider: requestId);
if (transaction != null) await transaction.WaitAsync(all: true);
}4. 월요일 한정 미션 추가하기
월요일에 모험을 한 번 클리어하면 30코인을 받는 미션을 추가합니다. 월요일에 달성해 두면 화요일부터 일요일 사이에도 보상을 받을 수 있습니다. 다음 월요일 자정에 달성·수령 상태가 초기화되어 다시 도전할 수 있습니다. 이 예제의 요일과 시각은 일본 시간(JST, UTC+9) 기준입니다.
기존 clear3은 그대로 두고 주간 그룹 weekly에 monday_clear를 추가합니다.
월요일 일정 만들기
Tables → Scheduling → Schedule 에 다음 행을 추가합니다. 시작·종료 일시는 셀을 열고 Local (UTC+9) 로 전환한 뒤 날짜와 시각을 선택합니다.
| 항목 | 입력할 값 |
|---|---|
| ID | monday |
| 일정 방식 | absolute |
| 시작 일시 | 2020-01-01 00:00(일본 시간) |
| 종료 일시 | 2099-01-01 00:00(일본 시간) |
| 반복 방식 | weekly |
| 시작 요일 | sunday |
| 시작 시각 | 15 |
| 종료 요일 | monday |
| 종료 시각 | 15 |
시작·종료 일시는 이 주간 이벤트를 운영할 전체 기간입니다. 반복 설정으로 그 기간 중 매주 월요일에만 활성화합니다. 요일과 시각 필드는 UTC 기준이므로 일본 시간 월요일 0시부터 화요일 0시까지를 sunday 15부터 monday 15로 지정합니다.
주간 미션 만들기
리셋 시각은 일본 시간 월요일 자정입니다(미션 설정의 sunday, 15).
- MissionCollection 에
weekly를 추가합니다. 리셋 단위는weekly, 개최 일정은monday로 설정합니다. - Mission 에
monday_clear를 추가합니다. 그룹은weekly, 카운터는clear, 목표값은1로 설정합니다. 완료 보상은clear3과 같은 30코인입니다. - 저장하고 Publish → Calculate server differences 에서 배포한 뒤 Update the Unity project 를 실행합니다.
- 재생을 멈추고
Gs2의 Adventure Studio View 에서 Mission Group 을weekly, Mission Name 을monday_clear로 바꿉니다.
- 월요일 한정 미션 템플릿을 다운로드합니다.
- Deploy → adventure-daily → Update stack 을 열고 Template data 에서 파일을 선택해 업데이트합니다. Update complete 가 될 때까지 기다립니다.
- 재생을 멈추고 Adventure Daily 의 Mission Group 을
weekly, Mission Name 을monday_clear로 바꿉니다.
템플릿에는 로그인 보너스와 기존 clear3에 더해 다음 설정이 들어 있습니다. 날짜를 수정할 필요는 없습니다.
| 설정 | 내용 |
|---|---|
일정 monday | 매주 월요일 0시부터 화요일 0시까지 활성화(일본 시간) |
그룹 weekly | 매주 월요일 0시에 달성·수령 상태 초기화(일본 시간) |
미션 monday_clear | 카운터 clear, 목표값 1, 보상 30코인 |
일정의 반복 설정은 다음과 같습니다. GS2의 요일과 시각은 UTC 기준이므로 일본 시간 월요일 0시부터 화요일 0시까지를 일요일 15시부터 월요일 15시로 지정합니다.
"repeatSetting": {
"repeatType": "weekly",
"beginDayOfWeek": "sunday",
"beginHour": 15,
"endDayOfWeek": "monday",
"endHour": 15
}미션의 challengePeriodEventId가 이 일정을 참조합니다. 그룹 리셋도 resetType = weekly, resetDayOfWeek = sunday, resetHour = 15로 설정되어 있습니다.
배포 후 추가한 미션 설정이 적용되기까지 최대 5분이 걸릴 수 있습니다. 5분을 기다린 뒤 재생하고 로그인해 숲 탐험을 한 번 클리어합니다. 월요일이면 ‘미션 보상 30코인을 받을 수 있습니다’라고 표시됩니다. 화요일부터 일요일에는 클리어해도 미션이 달성되지 않습니다.
카운터는 기존 누적값을 사용합니다. 모험 클리어로 카운터가 증가할 때 달성 여부를 판정하므로, 누적값이 이미 1 이상이어도 월요일에 한 번 더 클리어해야 합니다.
| 시점 | 미션 동작 |
|---|---|
| 월요일에 모험 클리어 | 미션을 달성하고 30코인을 받을 수 있음 |
| 화요일부터 일요일 | 새로 달성할 수 없음. 월요일에 달성한 보상은 받을 수 있음 |
| 다음 월요일 0시 | 달성·수령 상태 초기화. 받지 않은 지난주 보상은 이월되지 않음 |