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


# キャラクターを集めて育てる

森で仲間を獲得し、ガチャ、経験値による強化、3枠のパーティ編成を作ります。



森の探索で「騎士」を1体もらい、ガチャでは騎士か魔法使いを獲得できるようにします。同じ騎士を2体持ったときも、別々に育ててパーティに入れられる形にします。

## 1. キャラクターの種類と所持枠を用意する


**Studio**

**機能を追加**で「キャラクター」を追加します。**表 → キャラクター**で、次の三つの表を編集します。セルは選択して Enter、配列はセルをダブルクリックして編集します。

| 表 | 行 | 入力する内容 |
| --- | --- | --- |
| キャラクター所持枠（CharacterCollection） | **行を追加**を押す（IDの入力は不要） | 初期所持枠 `20`、最大所持枠 `100` |
| キャラクター経験値（CharacterExperience） | **行を追加**を押す（IDの入力は不要） | 必要経験値テーブルに `1`、`10`、`20` を順に追加。初期レベル上限と最大レベル上限は `4` |
| キャラクター（Character） | 行を追加して `knight` | 表示順 `1` |
| キャラクター（Character） | 行を追加して `mage` | 表示順 `2` |

**反映 → サーバとの差分を確認**からデプロイし、続けて **Unity プロジェクトを更新する**を押します。所持データは `Character`、経験値は `CharacterExperience` のネームスペースに保存されます。


**SDK（Unity）**

<a href="/samples/adventure/extensions/characters.json" download>キャラクター設定のテンプレート</a>をダウンロードします。マネージメントコンソールの東京リージョンで **Deploy → スタックリスト → スタックを新規作成**を開きます。名前を `adventure-characters` とし、**テンプレートデータ**でダウンロードしたファイルを選び、作成します。

このスタックには、所持枠・経験値・ガチャ・編成の設定が入っています。既存の `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体のスタック数は1です。同じ種類を何度も獲得できるよう、`allowMultipleStacks` を `true` にしています。




### 森のクリア報酬に騎士を加える


**Studio**

**表 → クエスト → クエスト（Quest）** の `forest` で **通常クリア報酬**を開きます。コイン・ミッションカウンター・回復薬のアクションを残して、**アイテムを追加 → 未設定**を押します。`AcquireItemSetByUserId`（アイテムを取得）を選び、次を入力します。

| 項目 | 値 |
| --- | --- |
| namespaceName | `Character` |
| userId | `#{userId}` |
| inventoryName | `Character` |
| itemName | `knight` |
| acquireCount | `1` |

保存してサーバーへ反映します。


**SDK（Unity）**

`adventure-game` の現在のテンプレートを開き、`main` の `forest` にある `contents` → `completeAcquireActions` の末尾へ、次の1件を追加します。既存のコイン・ミッションカウンター・回復薬の項目は残します。変更したテンプレート全体でスタックを更新してください。

```yaml
- action: Gs2Inventory:AcquireItemSetByUserId
  request: |-
    {"namespaceName":"adventure-character","userId":"#{userId}","inventoryName":"Character","itemName":"knight","acquireCount":1}
```




### Unity に所持一覧を表示する

Unity の再生を止め、`Extensions` の **Adventure Items** のチェックを外します。左側の冒険画面はそのまま使います。


**Studio**

<a href="/samples/adventure/extensions/studio/AdventureCharacters.cs" download>AdventureCharacters.cs</a> を `Assets/AdventureExtensions` に入れ、`Extensions` に **Adventure Characters** を追加します。接続には、ログイン済みの `Gs2ClientHolder` と `Gs2GameSessionHolder` を使います。


**SDK（Unity）**

<a href="/samples/adventure/extensions/sdk/AdventureCharacters.cs" download>AdventureCharacters.cs</a> を `Assets/AdventureExtensions` に入れ、`Extensions` に **Adventure Characters** を追加します。**Login** に、シーン内の `AdventureLogin` を割り当てます。




再生し、左側の画面で森を新しく開始してクリアします。右側の所持一覧に、`knight` と個体を区別する値が表示されます。もう一度森をクリアすると、同じ `knight` が別々の2行になります。報酬の追加が反映されるまで最大5分かかります。騎士が増えない場合は、少し待ってから森を新しく始めてクリアします。

初回は次の呼び出しで一覧を取得し、その後は `SubscribeItemSets()` で増減を受け取ります。`ItemName` が種類、`ItemSetId` が1体ずつの識別子です。

```csharp
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コインでガチャを引く


**Studio**

**機能を追加**で「キャラクターガチャ」を追加します。**表 → キャラクターガチャ**で、次の順に行を作ります。

| 表 | ID | 入力する内容 |
| --- | --- | --- |
| レアリティ（GachaRarity） | `common` | IDのみ |
| ガチャ（Gacha） | `normal` | 開催スケジュールは空欄 |
| レアリティ排出率（GachaRarityRate） | 行を追加 | 対象ガチャ `normal`、レアリティ `common`、抽選重み `1` |
| キャラクター排出率（CharacterRate） | 行を追加 | レアリティ `common`、キャラクター `knight`、抽選重み `1` |
| キャラクター排出率（CharacterRate） | もう1行追加 | レアリティ `common`、キャラクター `mage`、抽選重み `1` |

排出率の表では、参照先を選ぶと ID が自動で決まります。ID セルには入力しません。

`normal` の **1回の抽選コスト**を開き、`WithdrawByUserId` を1件追加します。`namespaceName = Currency`、`userId = #{userId}`、`slot = 0`、`withdrawCount = 20`、`paidOnly = false` とします。保存し、サーバーと Unity へ反映します。


**SDK（Unity）**

最初に適用した `characters.json` の `LotteryMaster` と `ShowcaseMaster` が、この設定です。二つの景品の重みはどちらも1、商品の消費アクションは20コイン、獲得アクションは `Gs2Lottery:DrawByUserId` です。




左側の冒険画面でコインを20枚以上集めてから、右側の**20 コインでガチャを引く**を押します。所持一覧に騎士か魔法使いが1体追加されます。左側のコインが20枚減ったことも確認します。

購入には Showcase を使い、その獲得アクションから Lottery の抽選を実行します。

```csharp
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. 選んだ1体に経験値を与える

強化には、10コインの消費と経験値10の付与を組み合わせた Exchange を使います。


**Studio**

<a href="/samples/adventure/extensions/character-training-studio.json" download>Studio のキャラクター向け強化設定</a>をダウンロードします。マネージメントコンソールの **Deploy → スタックを新規作成**で、名前を `adventure-character-training` とし、**テンプレートデータ**でダウンロードしたファイルを選んで作成します。Studio が作った `Currency` と `CharacterExperience` を参照する設定です。


**SDK（Unity）**

<a href="/samples/adventure/extensions/character-training-sdk.json" download>SDK のキャラクター向け強化設定</a>をダウンロードします。**Deploy → スタックを新規作成**で名前を `adventure-character-training` とし、**テンプレートデータ**でダウンロードしたファイルを選んで作成します。`adventure-coin` と `adventure-character-experience` を参照します。




1. 右側の所持一覧で、強化する個体の行を選びます。
2. **選んだ個体の経験値を読む**を押し、現在値を控えます。
3. **10 コインで経験値を 10 増やす**を押します。経験値の表示が自動で更新され、10増えます。
4. 別の個体を選んで経験値を読み、そちらの経験値は増えていないことを確かめます。

ボタンを押した時点で選んでいた `ItemSetId` を `Train()` に渡します。コードはその値に `:level` を付けて、経験値の保存先を指定します。`config` の値がテンプレート内の `#{propertyId}` に入ります。

```csharp
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. 3枠のパーティを保存する


**Studio**

**機能を追加**で「パーティ編成」を追加します。**表 → パーティ編成**で次を入力し、サーバーと Unity へ反映します。

| 表 | 行 | 入力する内容 |
| --- | --- | --- |
| 編成（CharacterFormation） | **行を追加**を押す（ID の入力は不要） | 初期保存枠 `1`、最大保存枠 `1` |
| 編成スロット（CharacterFormationSlot） | `slot1`、`slot2`、`slot3` の3行を追加 | 配置条件は各行とも `.*` |


**SDK（Unity）**

`characters.json` の `FormationMaster` に3枠を設定済みです。`CharacterFormation` の保存先 `0` を使います。




1. **編成を読み込む**を押してから、所持一覧で1体を選び、**スロット 1 に選んだ個体を入れる**を押します。
2. 別の個体を選び、スロット2へ入れます。3体あればスロット3にも入れます。空き枠は空のまま保存できます。
3. **編成を保存する**を押します。
4. 再生を止めて再開し、同じプレイヤーでログインして **編成を読み込む**を押します。同じ個体IDが各枠に表示されます。

保存時は Inventory の `GetItemWithSignatureAsync()` で所持を証明する署名を取得し、Formation の `SetFormAsync()` に渡します。コードには、同じ個体を二つの枠へ入れたときのチェックも入っています。

[次へ：プレイヤー同士をつなぐ]()



