コマース

【PlayFab】ドロップテーブルを使ってアイテムを付与する手順

playfab-drop-table

PlayFab のドロップテーブルを使うことで、「10%の確率で武器のアイテムをドロップする」という処理ができるんです。

公式ドキュメントにもドロップテーブルの使い方について記載がありますが、この記事ではさらに踏み込んで解説していきます。

では、さっそく見ていきましょう。

ドロップテーブルを使ってアイテムを付与する手順

付与するアイテムの登録

まずは、アイテムの登録が必要です。

ゲーム内のカタログにアイテムを追加する方法を参考に、ドロップテーブルに登録したいアイテムを作りましょう。

参考までに、私は以下のようにアイテムを作成しました。

drop-item-sample
ペンギンくん
ペンギンくん
何だかお腹が空いてきそうなアイテム…

ドロップテーブルの登録

アイテムが登録できたら、ドロップテーブルを登録します。

ドロップテーブルを作成する方法を見ながら、ドロップテーブルを作成しましょう。

テーブルIDと加重は好きなように設定して構いません。

drop-table-sample

加重が大きいほどドロップする確率が上がり、小さいほど確率が下がる仕組みです。

とてもわかりやすいですね。

サーバー処理の実装

ねこじょーかー
ねこじょーかー
Azure関数を使うので、Azure関数でCloudScriptを実行する方法を読んでから戻ってきてね!

今回は DropItem という関数を、Azure に登録することにします。

まずは全体像を見てみましょう。

[FunctionName("DropItem")]
public static async Task<dynamic> DropItem(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
  string body = await req.ReadAsStringAsync();
  var context = JsonConvert.DeserializeObject<FunctionExecutionContext<dynamic>>(body);
  var args = context.FunctionArgument;

  // 引数でテーブル名を渡す
  dynamic dropTableName = null;
  if (args != null && args["DropTableName"] != null)
    dropTableName = args["DropTableName"];

  // ドロップテーブルからアイテムを取得する
  var evaluateResult = await EvaluateRandomResultTable(context, dropTableName);
  // プレイヤーにアイテムを付与する
  var grantResult = await GrantItemsToUser(context, new List<string>() { evaluateResult });

  return PlayFabSimpleJson.SerializeObject(grantResult);
}

private static async Task<string> EvaluateRandomResultTable(FunctionExecutionContext<dynamic> context, dynamic dropTableName)
{
  var serverApi = new PlayFabServerInstanceAPI(context.ApiSettings, context.AuthenticationContext);

  var result = await serverApi.EvaluateRandomResultTableAsync(new PlayFab.ServerModels.EvaluateRandomResultTableRequest()
  {
    TableId = dropTableName
  });

  return result.Result.ResultItemId;
}

private static async Task<List<PlayFab.ServerModels.GrantedItemInstance>> GrantItemsToUser(FunctionExecutionContext<dynamic> context, List<string> itemIds)
{
  var serverApi = new PlayFabServerInstanceAPI(context.ApiSettings, context.AuthenticationContext);

  var result = await serverApi.GrantItemsToUserAsync(new PlayFab.ServerModels.GrantItemsToUserRequest()
  {
    PlayFabId = context.CallerEntityProfile.Lineage.MasterPlayerAccountId,
    ItemIds = itemIds
  });

  return result.Result.ItemGrantResults;
}

ちょっと長いですが、全体の流れとしては以下のとおりです。

  1. 引数でテーブル名をもらう
  2. もらったテーブル名のドロップテーブルで、アイテムを1つドロップ
  3. ドロップしたアイテムをユーザーに付与
  4. 付与した結果をクライアントに返す

引数のところは見たとおりなので、他のところを解説していきます。

ドロップテーブルでアイテムを1つドロップ

ドロップテーブルを使ってアイテムを1つドロップするには、EvaluateRandomResultTable を使います。

private static async Task<string> EvaluateRandomResultTable(FunctionExecutionContext<dynamic> context, dynamic dropTableName)
{
  var serverApi = new PlayFabServerInstanceAPI(context.ApiSettings, context.AuthenticationContext);

  var result = await serverApi.EvaluateRandomResultTableAsync(new PlayFab.ServerModels.EvaluateRandomResultTableRequest()
  {
    TableId = dropTableName
  });

  return result.Result.ResultItemId;
}

API の引数では TableId だけを渡していますが、CatalogVersion も渡すことができます。

初期値は「プライマリのカタログ」になっているので、以下の画像を例に挙げると、指定しなければ Main のドロップテーブルが指定されます。

catalog-image

プライマリのカタログ以外からドロップテーブルを使う場合は、明示的に CatalogVersion を渡してあげる必要があるので、注意してください。

返り値は、ドロップしたアイテムのIDとしています。

ドロップしたアイテムをユーザーに付与

今度は GrantItemsToUser を使用して、取得したアイテムをユーザーに付与します。

private static async Task<List<PlayFab.ServerModels.GrantedItemInstance>> GrantItemsToUser(FunctionExecutionContext<dynamic> context, List<string> itemIds)
{
  var serverApi = new PlayFabServerInstanceAPI(context.ApiSettings, context.AuthenticationContext);

  var result = await serverApi.GrantItemsToUserAsync(new PlayFab.ServerModels.GrantItemsToUserRequest()
  {
    PlayFabId = context.CallerEntityProfile.Lineage.MasterPlayerAccountId,
    ItemIds = itemIds
  });

  return result.Result.ItemGrantResults;
}

今回は1つのアイテムの付与ですが、汎用性を上げるためにメソッドの引数では List でもらうようにしています。

返り値は、付与したアイテムのインスタンスとしました。

付与した結果をクライアントに返す

最終的には、以下の形でクライアントに返しています。

  return PlayFabSimpleJson.SerializeObject(grantResult);

インスタンスを返す場合は、サーバー側でシリアライズしておかないと、クライアントでデシリアライズできないので注意してください。

ペンギンくん
ペンギンくん
なるほど、サーバー処理については理解できたぞ。

クライアント処理の実装

次に、クライアントからサーバーの DropItem を呼び出す処理を書きます。

  • ファンクション名は DropItem
  • パラメータ名は DropTableName、値は PlayFab 管理画面で登録したテーブルID

Azure関数でCloudScriptを実行する方法を参考に、上記の内容で呼び出し処理を書いてみましょう。

あとは、成功時のコールバックでデシリアライズしてあげます。

}, (ExecuteFunctionResult result) =>
{
   var grantedItems = PlayFabSimpleJson.DeserializeObject<List<ItemInstance>>(result.FunctionResult.ToString());
}

サーバー側では、アイテムインスタンスは GrantedItemInstance というクラスなのですが、クライアント側では ItemInstance になります。

クライアント側の準備はこれで完了です。

ドロップしたくない場合はどうするか

勘のいい人は気づいたかと思いますが、ドロップテーブルを使用すると、必ず何かのアイテムをドロップしてしまいます。

つまり、このままだとハズレがないんですね。

ということで、最後にハズレの作り方を解説します。

ハズレ用アイテムの登録

考え方としては、「ハズレの場合は、ハズレ用のアイテムをドロップすればよい」ということになります。

なのでまずは、ハズレ用アイテムの登録をしていきましょう。

アイテム付与後、3秒で消費するようにしておけば、インベントリに何も残りません。

drop-losing-item
「使用時間は2秒以上にする必要があります」と書いてありますが、実際は3秒以上にしないとエラーになります。笑

ドロップテーブルに登録

あとは、ハズレのアイテムもドロップテーブルに登録してあげればOKです。

drop-table-losing-item
ペンギンくん
ペンギンくん
そもそもハズレアイテムを引いた時点で、付与しなければいいんじゃない?
ねこじょーかー
ねこじょーかー
確かに、そういう実装の方法でも良さそうだね!

もしハズレアイテムを付与した場合、クライアント側では、ハズレのアイテムIDで判断して処理を分岐すればよいでしょう。

if(grantedItems.First().ItemId == "LosingItem")
{
  // ハズレの場合の処理を書く
}

最後に

ドロップテーブルを使用してアイテムを付与する方法について解説しました。

クエストをクリアしたときなど、アイテムのドロップをしたいケースは多いと思います。

この記事を参考に、ぜひチャレンジしてみてください。

さらにレベルアップしたい人は、公式ドキュメントを見ながらさらに理解を深めてみましょう。

PlayFab の書籍も好評発売中!
playfab-book

PlayFab のことをもっと皆さんに知ってもらいたくて、合計500ページ以上にもなる書籍を5冊に分けて執筆しました。

私の知識をすべて詰め込んでいるので、ゲーム開発をさらに加速させたい方はぜひご覧ください。

COMMENT

メールアドレスが公開されることはありません。