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


# 5. 冒険の開始時にスタミナを消費する

冒険に出るたびにスタミナを使い、足りないときは回復を待つ仕組みを作ります。



ここからは、冒険にスタミナを使うようにしていきます。森の探索を始めるのに必要なのは 5。足りないときは回復を待つ、というルールにしましょう。

## 始める前に

進行中の冒険があればクリアしてから、スタミナの設定を追加します。

## 追加する設定

スタミナの設定には `stamina` という名前を付けます。最初の値は 20、通常の回復上限も 20 です。冒険で使った分は、300 秒ごとに 1 ずつ自然に回復するようにします。

## 手順



**Studio**

### スタミナの表を作る

**機能を追加**で「スタミナ」を追加し、**表 → スタミナ（Energy）** に次の行を作ります。

| 項目 | 値 |
| --- | --- |
| ID | `stamina` |
| 初期上限（defaultMaximum） | `20` |
| 上限超過を許可（useOverflow） | オフ |
| 超過時上限（overflowedMaximum） | `20` |
| 回復間隔（recoveryIntervalMinutes） | `5`（分） |
| 1回の回復量（recoveryValue） | `1` |

回復間隔の入力単位は**分**です。300 秒にしたいので、入力するのは `5` です。

<a href="/images/adventure/later-chapters/05-stamina-settings.jpg" target="_blank" rel="noopener" aria-label="スタミナの表。stamina の上限20、上限超過なし、回復間隔5分、回復量1を設定する（別タブで拡大）"><img src="/images/adventure/later-chapters/05-stamina-settings.jpg" alt="スタミナの表。stamina の上限20、上限超過なし、回復間隔5分、回復量1を設定する" loading="lazy"></a>

**クエスト（Quest）** の `forest` の **開始時消費** をダブルクリックします。**アイテムを追加 → 未設定** を開き、アクションで `ConsumeStaminaByUserId`（スタミナを消費）を選びます。ターゲットリソースは **なし** のまま、次の値を入力します。

| 項目 | 値 |
| --- | --- |
| namespaceName | `Energy` |
| staminaName | `stamina` |
| userId | `#{userId}` |
| consumeValue | `5` |

<a href="/images/adventure/later-chapters/05-consume-stamina.jpg" target="_blank" rel="noopener" aria-label="クエストの開始時消費。Energy の stamina から consumeValue 5 を消費する（別タブで拡大）"><img src="/images/adventure/later-chapters/05-consume-stamina.jpg" alt="クエストの開始時消費。Energy の stamina から consumeValue 5 を消費する" loading="lazy"></a>

通常クリア報酬は第3章のまま、`Currency` のスロット `0` に10コインを入金します。

サーバーへデプロイし、Unity を更新します。

<a href="/samples/adventure/05/AdventureStudioView.cs" download>この章の AdventureStudioView.cs</a> をダウンロードし、既存の `Assets/AdventureStudioView.cs` を置き換えます。

Unity の `Gs2` オブジェクトに `EnergyHandler` を追加して **Id** を `stamina` にし、`AdventureStudioView` の **Energy** に割り当てます。

現在値の表示は `DrawPlayerStatus()` にまとめています。ハンドラーが更新したスタミナも、この中で表示します。

```csharp
private void DrawPlayerStatus()
{
    GUILayout.Label(wallet.HasValue
        ? "コイン: " + wallet.Model.Free
        : "コインを読み込み中です");

    if (!progress.HasValue)
    {
        GUILayout.Label("進行を読み込み中です");
    }
    else
    {
        GUILayout.Label(progress.Model.InProgress
            ? "冒険中です"
            : "冒険を選んでください");
    }

    GUILayout.Label(energy.HasValue
        ? "スタミナ: " + energy.Model.CurrentValue
        : "スタミナを読み込み中です");
}
```




**SDK（Unity）**

### 設定を更新する

<a href="/samples/adventure/05/adventure-game.yaml" download>第5章のテンプレートをダウンロード</a>し、**Deploy → adventure-game → スタックを更新**を開き、**テンプレートデータ**でダウンロードしたファイルを選びます。これは前の章のリソースも含む完全なテンプレートです。更新内容を確認して適用し、実行状態が**更新完了**になるまで待ちます。

テンプレートのスタミナ設定は次の値です。`recoverIntervalMinutes` は分単位なので、300 秒ではなく `5` と書きます。

```yaml
staminaModels:
  - name: stamina
    initialCapacity: 20
    isOverflow: false
    maxCapacity: 20
    recoverIntervalMinutes: 5
    recoverValue: 1
```

開始時消費には `Gs2Stamina:ConsumeStaminaByUserId` を設定し、`staminaName = stamina`、`consumeValue = 5` を渡します。Unity の開始ボタンは第3章と同じ `StartAsync()` を呼びます。

### Unity のコードを更新する

次の二つのファイルを `Assets` に入れます。同名ファイルがある場合は置き換えてください。

- <a href="/samples/adventure/05/AdventurePlay.cs" download>AdventurePlay.cs</a>：冒険の操作と画面表示
- <a href="/samples/adventure/05/AdventurePlayer.cs" download>AdventurePlayer.cs</a>：表示用データの購読と解除

Inspector の設定はそのまま使えます。

この章で使う処理は次の部分です。抜粋を別のクラスとして追加する必要はありません。

```csharp
var meter = Gs2.Stamina.Namespace("adventure-stamina").Me(Session).Stamina("stamina");
var subscription = await meter.SubscribeWithInitialCallAsync(value => Stamina = value);
```

消費や購入による変更は、このコールバックで表示に反映します。自然回復は、描画時に SDK の `PredictRecovery()` で反映します。返ってきた値を表示すれば、待っている間もスタミナが増えていきます。

```csharp
using Gs2.Unity.Gs2Stamina.Model;

var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
    + (player.Session.AccessToken.TimeOffset ?? 0) * 1000L;
var stamina = player.Stamina.PredictRecovery(now);
GUILayout.Label("スタミナ: " + stamina.Value + " / " + stamina.MaxValue);
```

`now` はセッションの時刻に合わせたミリ秒です。`PredictRecovery()` は購読で受け取った元のデータを変更せず、自然回復後の値を返します。






## スタミナを使ってみましょう

これまで使ってきたプレイヤーで試します。消費量の設定が反映されるまで最大5分かかります。まだスタミナが減らない場合は、その冒険をクリアし、少し待ってから新しく始めて確かめます。

1. スタミナが 5 以上あることを確認し、現在の値を控えます。
2. 森の探索を始め、スタミナが開始前より 5 減ったか見てみましょう。たとえば、20 なら 15 になります。
3. 冒険をクリアし、コインが 10 増えたことも確かめます。

操作の間に自然回復した場合は、その回復分も加えて比べてください。

## 練習：設定を変えて試す

冒険に必要なスタミナを 8 に変えてみましょう。Studio は開始時消費の `consumeValue`、SDK はテンプレートの `consumeValue` を `8` にしてデプロイします。

スタミナが 8 以上ある状態で森の探索を始め、開始前より 8 減ることを確認します。足りない場合は自然回復を待ちます。まだ 5 しか減らない場合は、その冒険をクリアし、少し待ってから新しく始めます。確認できたら冒険をクリアし、消費量を **5 に戻してデプロイ** してください。通常報酬は 10 コインのままです。

## スタミナが足りないときの動きを確かめる

消費量を戻したデプロイから5分待って、森の探索を新しく始めます。スタミナが 5 減ることを確かめてクリアしてから、不足する状態を作ります。

1. 森の探索の開始とクリアを繰り返し、スタミナを 5 未満にします。
2. もう一度開始ボタンを押します。エラーメッセージが表示され、冒険が始まらないことを確認します。
3. 失敗した操作では、スタミナが消費されていないことも確かめます。

スタミナは 300 秒ごとに 1 ずつ自然回復します。5 以上に戻ると、また冒険を始められます。

[次へ：コインでスタミナを回復する]()



