> For the complete documentation index, see [llms.txt](/ko/llms.txt)


# 6. 코인으로 스태미나 회복하기

작은 상점을 만들어 모은 코인으로 스태미나를 회복해 봅니다.



퀘스트에서 모은 코인을 사용해 봅시다. 20코인으로 스태미나를 10 회복하는 상품을 `refill`이라는 이름으로 등록합니다. 퀘스트 보상으로 받은 무상 코인으로 구매할 수 있게 합니다.

## 결제와 회복을 함께 처리하기

코인 지불과 스태미나 회복을 하나의 트랜잭션으로 묶습니다. 코인이 부족하면 스태미나만 회복되는 일 없이 구매가 실패하도록 합니다.

## 따라 하기



**Studio**

### 상품 표 만들기

**Add features** 에서 **Stamina Shop** 을 추가하고 **Tables → Stamina product (EnergyProduct)** 에 다음 행을 만듭니다.

| 항목 | 값 |
| --- | --- |
| ID | `refill` |
| 회복 대상 (energy) | `stamina` 행 |
| 회복량 (recoveryValue) | `10` |
| 구매 비용 (consumeActions) | 아래 소비 액션 1개 |

**Purchase cost** 셀을 더블 클릭하고 **Add item → Not set** 을 엽니다. `WithdrawByUserId`(지갑 잔액 소비)를 선택하고 **Target resource** 는 **None** 으로 둔 채 다음 값을 입력합니다.

| 항목 | 값 |
| --- | --- |
| namespaceName | `Currency` |
| userId | `#{userId}` |
| slot | `0` |
| withdrawCount | `20` |
| paidOnly | `false` |

`paidOnly`를 `false`로 설정하면 이 튜토리얼에서 모은 무상 코인으로 지불할 수 있습니다.

<a href="/images/adventure/later-chapters/06-shop-cost.jpg" target="_blank" rel="noopener" aria-label="구매 비용 설정. Currency 슬롯 0에서 20코인을 지불하고 paidOnly는 false (새 탭에서 확대)"><img src="/images/adventure/later-chapters/06-shop-cost.jpg" alt="구매 비용 설정. Currency 슬롯 0에서 20코인을 지불하고 paidOnly는 false" loading="lazy"></a>

오른쪽 편집 영역을 닫습니다. `refill`의 회복 대상이 `stamina`, 회복량이 `10`, 구매 비용이 1개인지 확인하고 저장합니다.

<a href="/images/adventure/later-chapters/06-shop-product.jpg" target="_blank" rel="noopener" aria-label="스태미나 상품 refill의 회복량은 10이며 구매 비용 액션은 1개 (새 탭에서 확대)"><img src="/images/adventure/later-chapters/06-shop-product.jpg" alt="스태미나 상품 refill의 회복량은 10이며 구매 비용 액션은 1개" loading="lazy"></a>

서버에 배포하고 Unity를 업데이트합니다. `AdventureStudioView.cs`를 이 장의 코드로 교체하면 구매 버튼이 추가됩니다. 기존 Quests, Progress, Wallet, Energy 할당도 확인합니다.

스태미나 상점 패키지가 만드는 Exchange 네임스페이스는 `EnergyProduct`입니다. 구매 버튼이 호출하는 `Buy()`는 다음과 같습니다. 화면 배치와 현재 값 표시는 별도 메서드에 있습니다.

```csharp
private async Task Buy()
{
    var request = Gs2ClientHolder.Instance.Gs2.Exchange.Namespace("EnergyProduct")
        .Me(Gs2GameSessionHolder.Instance.GameSession).Exchange();
    var transaction = await request.ExchangeAsync("refill", 1, speculativeExecute: false);
    if (transaction != null) await transaction.WaitAsync(all: true);
}
```

<a href="/samples/adventure/ko/06/AdventureStudioView.cs" download>이 장의 AdventureStudioView.cs 다운로드</a>




**SDK (Unity)**

### 설정 업데이트하기

<a href="/samples/adventure/ko/06/adventure-game.yaml" download>6장 템플릿을 다운로드</a>하고 **Deploy → adventure-game → Update stack** 에서 **Template data** 로 파일을 선택합니다. 이전 리소스도 포함한 전체 템플릿입니다. 변경 내용을 확인하여 적용하고 **Update complete** 가 될 때까지 기다립니다.

템플릿의 `refill`은 `Gs2Money2:WithdrawByUserId`의 `withdrawCount = 20`, `paidOnly = false`와 `Gs2Stamina:RecoverStaminaByUserId`의 `recoverValue = 10`을 조합합니다. 교환 시점은 `timingType: immediate`입니다.

### Unity 코드 업데이트하기

<a href="/samples/adventure/ko/06/AdventurePlay.cs" download>AdventurePlay.cs</a>를 다운로드하여 `Assets`의 같은 이름 파일을 교체합니다. `AdventurePlayer.cs`는 5장의 파일을 그대로 사용합니다.

Inspector 설정은 그대로 사용합니다.

이 장에서 사용하는 부분은 아래와 같습니다. 이 발췌 코드를 별도 클래스로 추가할 필요는 없습니다.

```csharp
private async UniTask BuyRefill()
{
    var transaction = await player.Gs2.Exchange.Namespace("adventure-shop").Me(player.Session)
        .Exchange().ExchangeAsync("refill", 1, speculativeExecute: false);
    awaitingResult = true;
    if (transaction != null) await transaction.WaitAsync(all: true);
}
```






구매 중에는 버튼을 비활성화하고 완료되면 변경된 코인과 스태미나를 표시합니다.

## 상품 구매해 보기

지금까지 모은 코인으로 같은 플레이어의 스태미나를 회복합니다.

1. 코인이 20개 이상이고 스태미나가 10 이하인지 확인합니다. 코인이 부족하거나 스태미나가 많으면 숲 탐험을 시작하고 클리어하여 조정합니다.
2. 구매 전 코인과 스태미나를 기록하고 구매 버튼을 누릅니다.
3. 코인이 20 줄고 스태미나가 10 늘었는지 확인합니다. 예를 들어 코인 30, 스태미나 5였다면 코인 10, 스태미나 15가 됩니다.
4. Unity 재생을 중지했다가 다시 재생합니다. Studio는 자동 로그인하고 SDK는 **로그인** 을 누릅니다. 구매 후 잔액과 회복된 스태미나가 남아 있는지 확인합니다.

스태미나는 상한 20까지 회복됩니다. 조작이나 재실행 사이에 자연 회복되었다면 그만큼도 포함하여 비교합니다.

코인이 20개 미만이면 구매할 수 없고 오류 메시지가 표시됩니다. 실패한 구매로 코인이 줄거나 스태미나가 회복되지는 않습니다.

## 연습: 설정 바꿔 보기

가격을 25코인으로 바꿔 봅시다. 먼저 숲 탐험을 클리어하여 코인을 25개 이상, 스태미나를 10 이하로 맞춥니다. 표시 가격과 실제 소비량 모두 25인가요? 배포 후 소비 설정이 반영되기까지 최대 5분이 걸릴 수 있습니다. 25로 표시되어도 20코인만 줄어들면 잠시 기다렸다가 다음 구매로 확인합니다.

<details>
Studio에서는 상품 구매 비용의 `withdrawCount`, SDK에서는 템플릿의 `withdrawCount`를 `25`로 바꾸어 배포합니다. 확인용 버튼 문구는 고정되어 있으므로 `20코인으로 스태미나 10 회복`도 `25코인으로 스태미나 10 회복`으로 바꿉니다.


## 다음 장으로 넘어가기 전에

가격을 **20코인으로 되돌리고 화면 문구와 소비 설정을 모두 반영** 합니다. 회복량은 10으로 둡니다. 배포 후 5분을 기다리고 숲 탐험으로 코인을 모은 뒤 구매하여 20코인이 줄어드는지 확인하고 진행합니다.

[다음: 설정을 바꾸고 게임에 반영하기]()



