GS2-Showcase

商品販売機能

ゲーム内で商品を販売する際に使用します。

GS2-Exchange との違いは陳列棚が存在することです。 陳列棚には DisplayItem を陳列することができ、DisplayItem を購入するために必要な対価と、商品を購入した際に得られる報酬を設定できます。

陳列棚には2種類存在し、固定の DisplayItem が陳列される《スタンダード陳列棚》と、一定間隔で陳列内容がランダムに抽選される《ランダム陳列棚》が存在します。

スタンダード陳列棚

スタンダード陳列棚は指定した DisplayItem が全て陳列されます。 DisplayItem には2種類存在し《SalesItem》と《SalesItemGroup》が存在します。

SalesItem

SalesItem には購入するするために必要な対価と、購入した際に得られる報酬を設定できます。

SalesItemGroup

SalesItemGroup は購入回数に応じて販売する SalesItem が変化する仕組みを実現します。

SalesItemGroup には複数の SalesItem を属させることができ、リストの最後の商品以外には GS2-Limit のカウンター上昇を対価に設定する必要があります。 SalesItemGroup を陳列棚に陳列する際には、内部の SalesItem が購入可能かを判定し、一番最初に購入可能と判定された商品が陳列されます。

この機能を利用することで、初回購入のみ半額で商品を販売したり、購入するごとに価格が高くなっていく商品を実現したり、10回目の購入にはおまけをつける。というような商品を実現できます。

ランダム陳列棚

ランダム陳列棚は、マスターデータに指定した DisplayItem のうち指定した数がランダムに抽選されて陳列されます。 マスターデータを登録することでマイクロサービスで利用可能なデータや振る舞いを設定できます。

マスターデータの種類には以下があります。

  • ShowcaseModel: スタンダード陳列棚の定義
  • RandomShowcaseModel: ランダム陳列棚の定義

マスターデータの登録はマネージメントコンソールから登録する他、GitHubからデータを反映したり、GS2-Deployを使ってCIから登録するようなワークフローを組むことが可能です。

バフによる補正

GS2-Buff と連携すると DisplayItem および RandomDisplayItemModel の acquireActionsverifyActionsconsumeActions を動的に補正でき、ランダム陳列商品では stock の上書きも可能です。イベントやキャンペーンに合わせて報酬や必要対価、在庫数を柔軟に変更できます。

実装例

スタンダード陳列棚

陳列棚を取得

    var item = await gs2.Showcase.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Showcase(
        showcaseName: "showcase-0001"
    ).ModelAsync();
    const auto Domain = Gs2->Showcase->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Showcase(
        "showcase-0001" // showcaseName
    );
    const auto item = Domain.Model();

商品を購入

    var result = await gs2.Showcase.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Showcase(
        showcaseName: "showcase-0001"
    ).BuyAsync(
        displayItemId: "display-item-0001",
        quantity: 1,
    );
    const auto Domain = Gs2->Showcase->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Showcase(
        "showcase-0001" // showcaseName
    );
    const auto Future = Domain->Buy(
        "display-item-0001", // displayItemId
        nullptr, // quantity
        nullptr // config
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

ランダム陳列棚

陳列棚を取得

    var items = await gs2.Showcase.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).RandomShowcase(
        showcaseName: "showcase-0001"
    ).RandomDisplayItemsAsync(
    ).ToListAsync();
    const auto It = Gs2->Showcase->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->RandomShowcase(
        "showcase-0001" // showcaseName
    )->RandomDisplayItems(
    );
    TArray<Gs2::UE5::Showcase::Model::FEzRandomDisplayItemPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

商品を購入

    var result = await gs2.Showcase.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).RandomShowcase(
        showcaseName: "showcase-0001"
    ).RandomDisplayItem(
        displayItemName: "display-item-0001"
    ).RandomShowcaseBuyAsync(
        quantity: 1,
        config: null
    );
    const auto Future = Gs2->Showcase->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->RandomShowcase(
        "showcase-0001" // showcaseName
    )->RandomDisplayItem(
        "display-item-0001" // displayItemName
    )->RandomShowcaseBuy(
        1, // quantity
        nullptr // config
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

詳細なリファレンス