【Unity/C#】ゲーム制作ツール最強の一角『Azure PlayFab』オンライン機能を簡単に実装可能!

Unity/C#

Azure PlayFabとは?

PlayFabは、ゲームの運営や管理に必要なツールを一元化したLiveOpsプラットフォームです。リアルタイムでのデータ分析、プレイヤーデータ管理、仮想通貨やアイテム管理、マルチプレイヤー機能の提供など、多彩な機能を持ったMBaaSです。これにより、開発者はゲームの制作だけでなく、リリース後の運営やエンゲージメント向上にも注力できます。

MBaaS(Backend as a Service)

モバイルアプリやゲームアプリの開発者向けに提供されるクラウドベースのバックエンドサービスです。アプリ開発に必要なサーバーサイドの機能を、コードを書くことなく簡単に利用できるようにするプラットフォームを指します。

主な機能

サーバーレス運用
Azureと統合したPlayFabはスケーラビリティが高く、大規模なトラフィックにも対応可能。

プレイヤーデータ管理
プレイヤープロファイルや進行状況をクラウド上に保存。
カスタム統計データの追跡やプレイヤーごとの設定も可能。

仮想通貨とインベントリ管理
ゲーム内経済を簡単に構築し、アイテムや通貨を自由に管理。

マッチメイキングとマルチプレイヤー
高速かつ効率的なプレイヤーマッチメイキングを実現。

リアルタイム分析
プレイヤーの行動やゲーム内イベントのデータを即座に分析。
カスタムダッシュボードを作成して重要なKPIを把握。

Azure PlayFabの利点

  1. 柔軟性とスケーラビリティ
    小規模なインディーゲームから大規模なAAAタイトルまで対応可能。
  2. コスト管理が容易
    初期コストを抑えつつ、規模に応じたプランを選択可能。
  3. Azureとのシームレスな統合
    高可用性と高パフォーマンスを実現し、運用コストを最小限に抑える。

Azure PlayFabの料金プラン

PlayFabは無料プランから始めることができ、小規模なゲームプロジェクトやテスト段階に最適です。規模が拡大するにつれて、必要な機能やサポートレベルに応じた有料プランを選択できます。

無料プラン

  • 対象: 開発中のゲームや小規模プロジェクト。
  • 機能制限:
    • 100,000プレイヤーデータストレージ(MAU: 月間アクティブユーザー)
    • 基本的なデータ分析機能。
    • Azureの統合やリアルタイム分析は限定的。

スタンダードプラン

  • 料金: 月額 0.008ドル/MAU(1000MAUごとに8ドル)。
  • 特徴:
    • 無制限のプレイヤーデータ保存。
    • 高度なデータ分析とレポート機能。
    • APIリクエスト数の増加(1か月あたり最大1億件)。

エンタープライズプラン

  • 料金: カスタム見積もり(プロジェクトの規模に応じて設定)。
  • 特徴:
    • 専用の技術サポート。
    • 無制限のMAUとAPIリクエスト数。
    • カスタム機能の開発支援。

その他の料金情報

無料プランからの移行: 初期段階で無料プランを使用し、ユーザー数が増加したタイミングでスタンダードプランやエンタープライズプランにアップグレードするのが一般的です。

追加リソース: 必要に応じて、サーバーやストレージ、特定機能の追加利用分が課金されることがあります。

アカウント登録と初期設定

Microsoftアカウントの準備

PlayFabはMicrosoftアカウントでサインインします。まだアカウントをお持ちでない場合は、以下のリンクから作成してください。

PlayFabアカウント作成

  1. PlayFab公式サイトにアクセス: PlayFab公式サイト
  2. 右上の「Get Started Free」をクリック。
  3. Microsoftアカウントでサインイン。
  4. サインイン後、PlayFabの初期設定画面が表示されます。

タイトルの作成

タイトルとは?

PlayFabでは、ゲームごとに「タイトル」という単位でデータを管理します。

タイトルを作成する手順

  1. サインイン後、管理画面の「My Studios」を開く。
  2. Create New Title」をクリック。
  3. 必要な情報を入力:
    • Title Name: ゲームの名前
    • Studio Name: 制作スタジオ名
  4. 作成を完了すると、ゲーム専用の「Title ID」が発行されます。このIDは、ゲームとPlayFabを連携させる際に必要です。

SDKの導入

PlayFabをゲームに統合するには、SDKの導入が必要です。

対応プラットフォーム

PlayFabは多くのプラットフォームに対応しています。以下は主要なものです。

  • Unity
  • Unreal Engine
  • iOS / Android
  • HTML5 / JavaScript

Unityの場合

SDKがプロジェクトに正しく設定されていることを確認します。

Unity Asset Storeから「PlayFab Unity SDK」をインポート。

PlayFab Unity SDKのリンク

プロジェクトにインポート後、「PlayFabEditorExtensions」を開き、ログインを行う。

PlayFab用語解説

Azure Playfabの用語を理解することで、PlayFabの機能をより効率的に活用し、ゲーム開発に役立てることができます。

この記事で取り扱う

1. ユーザーデータ (User Data)
プレイヤーごとに保存されるカスタマイズ可能なデータ。ゲーム内の進行状況や設定、統計情報を保存するために使用されます。例えば、特定のアイテムの所持状況やゲームの難易度設定などが含まれます。

2. タイトルデータ (Title Data)
ゲーム全体で共有されるデータの集合。アイテムのステータス、クエストの条件、イベント情報など、すべてのプレイヤーに共通するデータが格納されます。サーバーサイドで管理され、頻繁に更新が必要な場合にも便利です。

3. プレイヤー名 (Player Display Name)
プレイヤーがゲーム内で他者に公開する名前。フレンド機能やリーダーボードでの表示、コミュニティイベントでの識別に使用されます。匿名性を保つために自動生成される場合もあります。

4. リーダーボード (Leaderboard)
ゲーム内でプレイヤーのスコアやランキングを管理・表示する仕組み。例えば、スコアや勝利数に基づいて、上位プレイヤーを競わせることができます。定期的なリセットや複数のカテゴリを設定することも可能です。

5. カタログ (Catalog)
ゲーム内で販売または使用されるアイテムの一覧。アイテムの価格や属性、入手条件が記載されています。カタログを利用することで、新しいコンテンツを簡単に追加できます。

6. インベントリー (Inventory)
プレイヤーが所持しているアイテムの管理機能。カタログ内のアイテムがプレイヤーに付与されるとインベントリーに保存されます。アイテムの使用、売却、交換などのアクションもここで管理されます。

7. ストア (Store)
プレイヤーがアイテムや仮想通貨を購入できる場所。カタログと連携して運用され、期間限定セールや特典付き商品を追加することも可能です。

8. 仮想通貨 (Virtual Currency)
ゲーム内での取引に使用されるデジタル通貨。プレイヤーがクエスト報酬として得たり、課金で購入したりすることで入手できます。複数種類の通貨を設定可能で、ゲーム経済の調整に役立ちます。

この記事では取り扱わない

9. プライズテーブル (Prize Table)
報酬をランダムに選択する仕組み。ガチャやランダムドロップで使用され、複数のアイテムや仮想通貨を含むことができます。アイテムのドロップ率を設定できるため、バランス調整に最適です。

10. キャラクター (Character)
プレイヤーが操作するアバターやユニット。1人のプレイヤーが複数のキャラクターを所有する場合もあり、各キャラクターに独自のデータやインベントリーを設定できます。RPGやキャラ育成ゲームにおいて重要な要素です。

11. コンテナ (Container)
ゲーム内でアイテムや報酬をまとめて提供する形式の要素。コンテナを開くことで、複数のアイテムや仮想通貨が手に入る場合があります。ガチャや宝箱の仕組みによく使用され、プライズテーブルと組み合わせることでランダム性を持たせることができます。


サンプルコード

PlayFabの主要な機能をある程度網羅した「PlayFabController.cs」というC#スクリプトを用意しました。

PlayFabController.cs – DOWNLOAD

解説

このコードでは、PlayFabをUnityプロジェクトで使用するための機能が定義されています。それぞれのメソッドについて解説します。

1. LoginWithCustomID

    /// <summary>
    /// ログイン
    /// </summary>
    /// <param name="customId"></param>
    public void LoginWithCustomID(string customId) {
        PlayFabClientAPI.LoginWithCustomID(new LoginWithCustomIDRequest
        {
            CustomId = customId,
            CreateAccount = true
        }, result =>
        {
            Debug.Log("ログインに成功しました");
            playFabId = result.PlayFabId;

            if (result.NewlyCreated) {
                Debug.Log("新しいアカウントを作成 ID:" + result.PlayFabId);
            }
        }, error =>
        {
            Debug.Log(error.GenerateErrorReport());
        });
    }
  • 概要: ユーザーをカスタムIDでログインさせます。
  • 引数: customId (カスタムID文字列)
  • 処理内容:
    1. カスタムIDを使ったログインリクエストを送信します。
    2. ログイン成功時にPlayFabIdが取得されます。
    3. 新規アカウントが作成された場合は、ログにその旨を出力します。

2. GetTitleData

    /// <summary>
    /// タイトルデータの取得
    /// </summary>
    public void GetTitleData() {
        PlayFabClientAPI.GetTitleData(new GetTitleDataRequest(),
            result =>
            {
                Debug.Log("タイトルデータの取得に成功しました");
                //var questMaster = PlayFab.Json.PlayFabSimpleJson.DeserializeObject<List<QuestMaster>>(result.Data["QuestMaster"]);//example
            }, error =>
            {
                Debug.Log(error.GenerateErrorReport());
            });
    }
  • 概要: PlayFabタイトルに設定されたデータを取得します。
  • 引数: なし
  • 処理内容:
    1. GetTitleDataRequestでタイトルデータを取得。
    2. 成功時にタイトルデータをログ出力します。
    3. 例としてJSONデータを特定のオブジェクト型に変換する部分がコメントされています。

3. UpdateUserData

    /// <summary>
    /// ユーザーデータの更新
    /// </summary>
    public void UpdateUserData() {
        PlayFabClientAPI.UpdateUserData(new UpdateUserDataRequest
        {
            Data = new Dictionary<string, string>
            {
                //{"ID",id }//example,
            },
            Permission = UserDataPermission.Public
        }, result =>
        {
            Debug.Log("ユーザーデータの更新に成功しました");
        }, error =>
        {
            Debug.Log(error.GenerateErrorReport());
        });
    }
  • 概要: プレイヤー固有のユーザーデータを更新します。
  • 引数: なし
  • 処理内容:
    1. 更新データをDataプロパティに設定。
    2. 成功時にはログに更新成功メッセージを出力。

4. GetUserData

    /// <summary>
    /// ユーザーデータの取得
    /// </summary>
    /// <param name="playFabId"></param>
    public void GetUserData(string playFabId) {
        PlayFabClientAPI.GetUserData(new GetUserDataRequest()
        {
            PlayFabId = playFabId
        }, result =>
        {
            Debug.Log("ユーザーデータの取得に成功しました");
        }, error =>
        {
            Debug.Log(error.GenerateErrorReport());
        });
    }
  • 概要: 特定ユーザーのデータを取得します。
  • 引数: playFabId (対象ユーザーのPlayFab ID)
  • 処理内容:
    1. 指定したPlayFabIdのデータをリクエスト。
    2. データ取得成功時にはログに出力します。

5. GetUserInventry

    /// <summary>
    /// インベントリーの取得
    /// </summary>
    private void GetUserInventry() {
        PlayFabClientAPI.GetUserInventory(new GetUserInventoryRequest
        {
        }, (result) =>
        {
            Debug.Log("インベントリーの取得に成功しました");
            Debug.Log(result.Inventory);
        }, (error) =>
        {
            Debug.Log(error.GenerateErrorReport());
        });
    }
  • 概要: プレイヤーのインベントリーを取得します。
  • 引数: なし
  • 処理内容:
    1. プレイヤーのインベントリーデータを取得。
    2. 成功時にログ出力します。

6. GetCatalogData

    /// <summary>
    /// カタログの取得
    /// </summary>
    /// <param name="catalogVersion"></param>
    public void GetCatalogData(string catalogVersion) {
        PlayFabClientAPI.GetCatalogItems(new GetCatalogItemsRequest()
        {
            CatalogVersion = catalogVersion,
        }, result =>
        {
            Debug.Log("カタログの取得に成功しました");
            //CatalogItems = result.Catalog;//example
            //GetStoreData("Items", "gold_store");//example
        }, error =>
        {
            Debug.Log(error.GenerateErrorReport());
        });
    }
  • 概要: カタログに登録されたアイテムリストを取得します。
  • 引数: catalogVersion (取得したいカタログのバージョン)
  • 処理内容:
    1. 指定されたカタログバージョンのアイテムリストを取得。
    2. 成功時にログに出力します。

7. GetStoreItems

    /// <summary>
    /// ストアの取得
    /// </summary>
    /// <param name="catalogVersion"></param>
    /// <param name="storeId"></param>
    public void GetStoreItems(string catalogVersion, string storeId) {
        PlayFabClientAPI.GetStoreItems(new GetStoreItemsRequest()
        {
            CatalogVersion = catalogVersion,
            StoreId = storeId
        }, (result) =>
        {
            Debug.Log("ストアの取得に成功しました");
            //StoreItems = result.Store;//example
        }, (error) =>
        {
            Debug.Log(error.GenerateErrorReport());
        });
    }
  • 概要: ストアの商品リストを取得します。
  • 引数:
    • catalogVersion: カタログバージョン
    • storeId: ストアID
  • 処理内容:
    1. ストアの商品リストを取得。
    2. 成功時にログ出力。

8. PurchaseItem

    /// <summary>
    /// アイテムの購入
    /// </summary>
    /// <param name="catalogVersion"></param>
    /// <param name="storeId"></param>
    /// <param name="itemId"></param>
    /// <param name="virtualCurrency"></param>
    /// <param name="price"></param>
    public void PurchaseItem(string catalogVersion, string storeId, string itemId, string virtualCurrency, int price) {
        PlayFabClientAPI.PurchaseItem(new PurchaseItemRequest()
        {
            CatalogVersion = catalogVersion,
            StoreId = storeId,
            ItemId = itemId,
            VirtualCurrency = virtualCurrency,
            Price = price

        }, purchaseResult =>
        {
            Debug.Log(purchaseResult.Items[0].DisplayName + "の購入に成功しました");
        }, error =>
        {
            Debug.Log(error.GenerateErrorReport());
            if (error.Error == PlayFabErrorCode.InsufficientFunds) {
                Debug.Log("金額が不足のため購入できませんでした");
            }
        });
    }
  • 概要: ストアからアイテムを購入します。
  • 引数:
    • catalogVersion: カタログバージョン
    • storeId: ストアID
    • itemId: アイテムID
    • virtualCurrency: 使用する仮想通貨
    • price: アイテムの価格
  • 処理内容:
    1. 指定アイテムを購入リクエスト。
    2. 成功時に購入したアイテムの名前をログ出力。
    3. 資金不足の場合はエラーをログ出力。

9. ConsumeItem

    /// <summary>
    /// アイテムの使用
    /// </summary>
    /// <param name="instanceId"></param>
    /// <param name="consumeCount"></param>
    public void ConsumeItem(string instanceId, int consumeCount) {
        PlayFabClientAPI.ConsumeItem(new ConsumeItemRequest
        {
            ItemInstanceId = instanceId,
            ConsumeCount = consumeCount

        }, (result) =>
        {
            Debug.Log(result.ItemInstanceId + "を" + consumeCount + "個使用しました");
        }, (error) =>
        {
            Debug.Log(error.GenerateErrorReport());
        });
    }
  • 概要: 所持アイテムを使用します。
  • 引数:
    • instanceId: 使用するアイテムのインスタンスID
    • consumeCount: 使用する個数
  • 処理内容:
    1. 指定アイテムを指定個数使用。
    2. 成功時にログに使用情報を出力。

10. UpdateUserTitleDisplayName

    /// <summary>
    /// プレイヤー名(表示名)の更新
    /// </summary>
    /// <param name="displayName"></param>
    public void UpdateUserTitleDisplayName(string displayName) {
        PlayFabClientAPI.UpdateUserTitleDisplayName(
            new UpdateUserTitleDisplayNameRequest
            {
                DisplayName = displayName
            }, result =>
            {
                Debug.Log("プレイヤー名の更新に成功しました");
            }, error =>
            {
                Debug.LogError(error.GenerateErrorReport());
            });
    }
  • 概要: プレイヤーの表示名を更新します。
  • 引数: displayName (新しい表示名)
  • 処理内容:
    1. 指定された名前にプレイヤーの表示名を更新。
    2. 成功時にログに更新成功メッセージを出力。

11. UpdatePlayerStatistics

    /// <summary>
    /// ランキングデータの送信
    /// </summary>
    /// <param name="leaderboardName"></param>
    /// <param name="score"></param>
    public void UpdatePlayerStatistics(string leaderboardName, int score) {
        PlayFabClientAPI.UpdatePlayerStatistics(
            new UpdatePlayerStatisticsRequest
            {
                Statistics = new List<StatisticUpdate> {
                    new StatisticUpdate {
                        StatisticName = leaderboardName,
                        Value = score
                    },
                }
            }, result =>
            {
                Debug.Log("ランキングデータの送信に成功しました");
            }, error =>
            {
                Debug.LogError(error.GenerateErrorReport());
            });
    }
  • 概要: ランキングに関連するスコアを送信します。
  • 引数:
    • leaderboardName: ランキング名
    • score: スコア値
  • 処理内容:
    1. ランキングデータをPlayFabに送信。
    2. 成功時にログ出力。

12. GetLeaderboard

    /// <summary>
    /// ランキングの取得
    /// </summary>
    /// <param name="leaderboardName"></param>
    /// <param name="startPosition"></param>
    /// <param name="maxResultsCount"></param>
    public void GetLeaderboard(string leaderboardName, int startPosition, int maxResultsCount) {
        PlayFabClientAPI.GetLeaderboard(
            new GetLeaderboardRequest
            {
                StatisticName = leaderboardName,
                StartPosition = startPosition,
                MaxResultsCount = maxResultsCount
            }, result =>
            {
                Debug.Log("ランキングデータの取得に成功しました");
                foreach (PlayerLeaderboardEntry entry in result.Leaderboard) {
                    Debug.Log($"{entry.DisplayName}: {entry.StatValue}");
                }
            }, error =>
            {
                Debug.LogError(error.GenerateErrorReport());
            });
    }
  • 概要: ランキングデータを取得します。
  • 引数:
    • leaderboardName: ランキング名
    • startPosition: 開始位置
    • maxResultsCount: 最大取得件数
  • 処理内容:
    1. ランキングデータをリクエスト。
    2. 取得したエントリーをログ出力。

13. GetVirtualCurrency

    /// <summary>
    /// 仮想通貨の取得
    /// </summary>
    public void GetVirtualCurrency() {
        PlayFabClientAPI.GetUserInventory(new GetUserInventoryRequest()
        {
        }, result =>
        {
            Debug.Log("仮想通貨の取得に成功しました");
            var virtualCurrency = result.VirtualCurrency["**"];
        }, error =>
        {
            Debug.Log(error.GenerateErrorReport());
        });
    }
  • 概要: プレイヤーの仮想通貨残高を取得します。
  • 引数: なし
  • 処理内容:
    1. インベントリーデータから仮想通貨情報を取得。
    2. 成功時に仮想通貨情報をログ出力。

14. AddUserVirtualCurrency

  • 概要: プレイヤーの仮想通貨を増加させます。
  • 引数:
    • virtualCurrency: 仮想通貨コード
    • amount: 増加させる額
  • 処理内容:
    1. 指定額の仮想通貨を追加。
    2. 成功時にログ出力。

15. SubtractUserVirtualCurrency

    /// <summary>
    /// 仮想通貨の減少
    /// </summary>
    /// <param name="virtualCurrency"></param>
    /// <param name="amount"></param>
    public void SubtractUserVirtualCurrency(string virtualCurrency, int amount) {
        PlayFabClientAPI.SubtractUserVirtualCurrency(new SubtractUserVirtualCurrencyRequest()
        {
            VirtualCurrency = virtualCurrency,
            Amount = amount
        }, result =>
        {
            Debug.Log("仮想通貨が減少しました");
        }, error =>
        {
            Debug.Log(error.GenerateErrorReport());
        });
    }
  • 概要: プレイヤーの仮想通貨を減少させます。
  • 引数:
    • virtualCurrency: 仮想通貨コード
    • amount: 減少させる額
  • 処理内容:
    1. 指定額の仮想通貨を減少。
    2. 成功時にログ出力。

まとめ

Azure PlayFabは、モバイルゲームからAAAタイトルまで、多種多様なゲームで活用されています。これらの事例は、PlayFabの機能がいかに広範囲にわたって適用できるかを示しています。自分のプロジェクトにもPlayFabを取り入れ、成功事例に続く一歩を踏み出してみてはいかがでしょうか?

ゲ制最高!

コメント

タイトルとURLをコピーしました