PlayFab
初期設定
-
PlayFabアカウントを作る。
-
新しいタイトルを作る。
-
ユーザー検索用のセグメントを作成
- InsideDayPlayers
- 前回のログイン が次の値以下 1440
-
タイトルIDとダッシュボード→設定から開発シークレットを取得
-
Unityでプロジェクトを作る。
-
UnitySDK https://github.com/PlayFab/UnitySDKを入れる。
-
Assets/PlayFabSDK/Shared/Public/Resouces/PlayFabSharedSettings
をクリックして、インスペクタで次を設定
- TitleID
- DeveloperSecuretKey
- RequestType を Unity Web Request
-
PlayFabSharedSettings を選んだ状態のままCtrl+Sまたはメニューから保存
-
警告が出るなら修正
-
PlayFabパーティ https://github.com/playfab/PlayFabPartyUnityを入れる。
-
UnitySDKが含まれるが、取り込まない
-
マイクは使わないが、使おうとしてリソースを探してエラーが出たり権限要求がでるなどあるので、SDKのソースを直接編集
PlayFabMultiplayerManager SetUserSettings PartyChatControlSetAudioInput PARTY_AUDIO_DEVICE_SELECTION_TYPE. PARTY_AUDIO_DEVICE_SELECTION_TYPE_PLATFORM_USER_DEFAULT → PARTY_AUDIO_DEVICE_SELECTION_TYPE_NONE
-
-
Android SDK 32 以降でエラーになるので修正
Assets\PlayFabPartySDK\Source\Scripts\PartyUnitySDK\PlayFabEventTracer.cs SetCommonTelemetryProperties // カスタマイズ #if UNITY_ANDROID payload["DeviceMake"] = SystemInfo.unsupportedIdentifier; #else payload["DeviceMake"] = SystemInfo.deviceName; #endif
SDK更新でやる事
-
バックアップを取る
C:\MyProjectFolder\Assets\PlayFabSDK\Shared\Public\Resources\ PlayFabSharedSettings.asset PlayFabSharedSettings.asset.meta -
Assets/PlayFabSDK を削除
-
Assets/PlayFabPartySDK を削除
-
UnitySDK https://aka.ms/PlayFabUnitySdkを入れる。
-
PlayFabパーティ https://github.com/PlayFab/PlayFabPartyUnity/releasesを入れるが、以下は除外
- Assets/PlayFabSDK
- Example
- Assets\PlayFabPartySDK\Source\DLLs\Linux
-
カスタマイズの反映
-
設定
-
バックアップファイルを戻してCtrl+R
-
Assets/PlayFabSDK/Shared/Public/Resouces/PlayFabSharedSettings
をクリックして、インスペクタで設定内容確認
- TitleID
- DeveloperSecuretKey
- RequestType を Unity Web Request
-
情報
-
初期設定
- EditorExtention もある。本来はこれを入れてログイン後にUnitySDKが入れられるが、ログインでMicrosoftIDが使えない
- CSharpSDK https://docs.microsoft.com/ja-jp/gaming/playfab/sdks/c-sharp/ というのもあるが、ビルドが通らないのとシークレットキーが入れられないので保留
-
- PC向けアプリでは Microsoft Game Development Kit (GDK)https://aka.ms/gdkdlが必要
- Unity + PlayFab Party を使う時の注意点 https://qiita.com/akiojin/items/ba956e8798844fa4fb88
-
PlayFabServerAPI.以下を使うとき
- プロジェクト設定 ー プレイヤー ー スクリプティング定義シンボルに ENABLE_PLAYFABSERVER_API を追加。
- プラットフォームごと
- プロジェクト設定 ー プレイヤー ー スクリプティング定義シンボルに ENABLE_PLAYFABSERVER_API を追加。
-
実行時に「failed to find specified resource」が出るのは、マイクがないため
- 参考 https://community.playfab.com/questions/51081/is-it-possible-to-disable-voice-on-playfab-party-u.html
- C# のSDKにはAPIがない。内部的には初期化があるが呼ぶ方法が分からなかった。
- PlayFabPlayer.IsMuted は呼べるがダメだった
- SDKのコードを直接編集。以下をNoneに設定
- PartyLocalChatControl::SetAudioInput()
- 参考 https://community.playfab.com/questions/51081/is-it-possible-to-disable-voice-on-playfab-party-u.html
-
プレイヤー取得 GetPlayersInSegment
- →いずれ廃止されるとのこと。
- 代わりは ExportPlayersInSegment または GetSegmentExport
- AllUsersセグメントではなく、最近接続した人というセグメントを作る
- 取得数上限があるが、続きをどう取るか
- ContinuationToken のようだ。取得結果に含まれるので再度与える
- 頻繁に呼ばれることを意図してないようなので、タイミングを遅くするかキャッシュを考える
- CloudScriptでもいいらしい。ランダム化もしやすいかも
- →いずれ廃止されるとのこと。
-
プレイヤーごとのデータ
-
PlayFabClientAPI.UpdateUserData
-
ReadOnlyData はServerAPIを有効にしないとクライアント側からは設定できない
- ただしServerAPIが無効ならそもそも他者のUserDataを変更できないので、ReadOnlyDataに置く必要が無い
-
-
プレイヤーにつけるタグ
- 最大5。資料によると10の場合もあった
-
ポータルで分析→データ
-
EventData.DeviceInfo.OperatingSystem
だとOS別で集計できる。最近Androidを更新したためか2項目あった
-
-
プレイヤー
- インベントリ
- 制限:1500
- 割と小さい。今 200 ぐらいだが、コンテナなどが加わることもある
- 設定で任意値に減らすことができる。カバンからあふれたなどが出来る
- 制限:1500
- プレイヤーデータ
- 制限:データ10KBx10個x1回の呼び出し
- 制限:全体のキー上限はないが30ぐらいまでにしてほしいらしい
- インベントリ
-
タイトルデータ
- 制限:値ごとに10KB
- 制限:単一のキーと値のペアのサイズの合計で1MBという記述
-
Group
- 制限:データ1KBx5個
- 制限:ファイル10個。サイズ上限は不明
-
制限:データ総合計はタイトル毎に50GB
-
SharedGroup
- 実質ルーム
- 自分で抜けるのはいいとして、切断や放置を削除する方法
- データ登録時間が標準で付いているので、一定以上経っていたらクライアント側で非表示
- クリーンアップを行う
- 一定数になったら参加できないように
- チャンネル番号は2桁。一部屋20人だったら2000人しか受けられない
- ポートにも使っているので桁を増やすのは慎重に
- チャンネル番号は2桁。一部屋20人だったら2000人しか受けられない
- 自分で抜けるのはいいとして、切断や放置を削除する方法
- 共有グループ内のユーザー列挙
-
PlayFabServerAPI.GetSharedGroupData
の GetMembers = true
-
- 制限:1プレイヤーに対して10のSharedGroup
- 制限:共有グループデータは10キーまでで、1つの値は10KB
- 制限:共有グループデータは多人数だとデータ保存の衝突が多くなるので設計に気を付けろとのこと
- 1つのSharedGroupに含められるプレイヤー数の上限は分からなかった
- 当面使用しない。イベントで使うかも
- 実質ルーム
-
エコノミー - カタログ - アイテム
- 消費型
- カウント
- アイテム一つ毎に何回使えるか。使い切ったら消滅
- タイム
- 一定時間のパワーアップなど。time group が同じアイテムを再使用すると延長
- 例えばリジェネ10秒とリジェネ20秒のアイテムがあるなど
- 今効果時間中かどうかの判定方法
- アイテムは所持すると一つずつに ItemInstanceID が振られる。
- そのID毎に有効期限がある
- イメージ的には、使用するとアイテムが減るが、by timeを指定すると減るまでの時間が延びる。その延びた時間の間が効果中
- item group nameを指定している場合は、どれを見ても有効期限が同じ
- アイテムは所持すると一つずつに ItemInstanceID が振られる。
- 一定時間のパワーアップなど。time group が同じアイテムを再使用すると延長
- カウント
- バンドル
- 初期アイテムを与えるのに使えそう
- 消費型
- カウント
- 中身は付与時点で得られるが、箱そのものが残る。使用すると無くなる。
- 連続取得を避けるため?基本使わなそう
- 中身は付与時点で得られるが、箱そのものが残る。使用すると無くなる。
- タイム
- 付与されたら時間で消える。短すぎると問題があるらしいので、2秒以上にする。再取得できないものなら長めの5秒でもいい
- カウント
- コンテナー
- ランダムアイテムが得られるアイテムを作る場合、コンテナにドロップテーブルを入れてコンテナをプレイヤーに付与する
- ドロップテーブル
- 終了後の報酬
- 3対戦毎の未取得優先には使え無さそう
- オンラインでは採用しない事にする
- 消費型
-
エンティティ
- プレイヤーとかグループの抽象クラスのイメージ
- 特に言及がないのでタイトル毎データのダウンロードのように有料ということが無さそう
- エンティティオブジェクト
-
JSON で格納
-
文字列そのままでも良い
-
JsonUtility で json を自分で生成するなら、入れるときに
SetObject.DataObject
ではなく
SetObject.EscapedDataObject
にする
-
制限:5個x1000バイト
-
プレイヤーデータの方が容量が大きいが、おそらく監視・分析はこちらが必要
-
- エンティティファイル
- 制限:10個。サイズ上限は無く、タイトル全体の総サイズで制限
- ファイル名とあるのは登録名であり、実体のファイルである必要はなかった
- 初期化・アップロード・フィニッシュの3ステップが必要
- 初期化後に止める時は中止が必要
- EntityKey = マスタープレイヤーアカウントのプレイヤーID
-
イベント
-
PlayFabClientAPI.WritePlayerEvent
- イベント名とKey-Valueで登録
-
イベントのエクスポートはAzureかAmazonのストレージ
-
-
CloudScript https://docs.microsoft.com/ja-jp/gaming/playfab/features/automation/cloudscript/writing-custom-cloudscript https://learn.microsoft.com/ja-jp/gaming/playfab/features/automation/cloudscript/
- 実行したプレイヤーのIDは currentPlayerId に入っている。
- context は、ポータル内からセグメント内ユーザーに対して実行した場合や、スケジュール済みタスクで「セグメント内の各プレイヤーに対してアクションを実行」で入る
-
context.playerProfile.PlayerId
-
- 結果はデータエクスプローラに載るが、反映に5分かかる。
-
PlayFabClientAPI.ExecuteCloudScript
での実行の場合は、result に含まれる Error を見る方が早い
-
- プレイヤーごとのデータの集計
- CloudScriptでプレイヤーごとのデータを取得。戻り値で結果を返す
- return { messageValue: value };
- 自動化 → スケジュール済みタスク
- タスクの種類をセグメント内の各プレイヤー・・・にする
- 対象をAll Users
- アクションをCloudScriptの関数
- 結果をPlayStream・・・にチェック
- 実行
- 少し待つ。イベントはすぐに反映されないため
- データ → データエクスプローラ
- クエリ
-
条件を追加
-
player_executed_cloudscript
-
句を追加
-
EventData.FunctionName
-
is equal to
-
関数名
-
-
-
グループ「
EventData.FunctionName
」
-
OS別の集計なら「
EventData.DeviceInfo.Platform
」
-
-
集計の種類はなんでも。データが数値の場合は Sum by
-
集計プロパティ「
EventData.CloudScriptExecutionResult.FuncitonResult.messageValue
」
-
-
- クエリ実行
- 今後も使うなら保存
- 終了日について、保存時は現在時刻より後に出来ないが、実行時に日付だけは変えられる。なので日付は0:00にして保存しておく
- CloudScriptでプレイヤーごとのデータを取得。戻り値で結果を返す
-
クエリ結果の保存は、データエクスプローラ(詳細設定)だとCSVで出来た
-
複雑なデータ集計
- データエクスプローラでは表現できないもの
- タイトルデータに集計値を入れるようにする
-
取り出し
let useCoinCounts = {}; const getTitleDataRequest = { "Keys": ["useCoinCounts"] }; const titleData = server.GetTitleInternalData(getTitleDataRequest); if (titleData.Data.hasOwnProperty("useCoinCounts")) { useCoinCounts = JSON.parse(titleData.Data["useCoinCounts"]); } -
保存
const setTitleDataRequest = { "Key": "useCoinCounts", "Value": JSON.stringify(useCoinCounts) }; server.SetTitleInternalData(setTitleDataRequest); -
json で入れるので、取り出しと保存で意識する必要があった。
-
-
ランキング
- 解説 https://qiita.com/_y_minami/items/9143502f465ad11ff2ca
- 不正防止のため、CloudScriptで行う
- 名前と数値のみ保持
- ランダムにユーザーを取得するためにランキングを利用した。
- 統計情報に登録する権限を与える必要があった。
- クライアント側の改ざんの可能性が出てくるので統計は使わないようにする
- 統計情報に登録する権限を与える必要があった。
-
アイテム売却 https://docs.microsoft.com/ja-jp/gaming/playfab/features/data/playerdata/player-inventory
- 直接的なAPIがないので、CloudScriptで行う
-
プレイヤー間トレード https://docs.microsoft.com/ja-jp/gaming/playfab/features/social/trading/
- クイックスタート https://docs.microsoft.com/ja-jp/gaming/playfab/features/social/trading/quickstart
- アイテム交換のみ。差分の貨幣付与もない
-
プレイヤーの各種データを取る
-
PlayFabServerAPI.GetAllSegments
で、列挙ユーザーのセグメントIDを得る
-
PlayFabServerAPI.GetPlayersInSegment
でユーザー列挙
- 取れるのはPlayerProfile
-
PlayerProfile.PlayerId
が PlayFabID
-
PlayFabID で
PlayFabServerAPI.GetUserAccountInfo
-
result.UserInfo.TitleInfo.TitlePlayerAccount.Id
が、 EntityKey.ID
-
-
EntityKey.ID から PlayFabID
-
CloudScriptで行う必要がある。クライアントに権限を与える方法もあるが避ける
-
const result = entity.GetProfiles({Entities: [args.EntityKey]});
-
server. ではない点に注意
-
単体用の entity.GetProfile もあるが、なぜかデータが一部しか得られない
-
result.Profile[0].Lineage.MasterPlayerAccountId
が PlayFabID
-
-
-
-
不具合
-
PlayFabMultiplayerManager.Get().CreateAndJoinNetwork
を行うと、
PlayFabMultiplayerManager.Get().OnNetworkJoined
が呼ばれるが、切断してもう一度行うと呼ばれない
- 対策としては切断せずに持ったままにする。切断イベントが来た時だけ作る
- https://community.playfab.com/questions/45860/playfab-c-unity-sdk-playfabmultiplayermanagerleave.html
- 更新したら直った、とあるが駄目だった。
- 1.6.0.0と1.5.0.3を試した
- 更新したら直った、とあるが駄目だった。
-
エコノミーv2
以前の物はレガシーとなり、メンテナンスモードになった。
- クレジットカード登録が必要
https://community.playfab.com/questions/66756/why-i-need-a-credit-card-for-economy-v2.html
サーバー保存データが5GBを超えると課金
1MBまでのリクエストが15万回を超えると課金
→恐らくユーザー作成コンテンツを対応するにあたって、総容量が大きくなるため
- ドロップテーブルが無くなった
- 言い分としては現在使われておらず、多くはCloudScriptでの独自実装をしているから
- 確率を動的に変えているところが多いのだろうか
- 言い分としては現在使われておらず、多くはCloudScriptでの独自実装をしているから
一方で、開発モードのタイトルだと課金されないという記述もある
ログの記憶は30日
- 定期的にやるなら忘れないようにタスクに入れる。例えば以下で一週間毎に各プレイヤーの集計処理が実行できる。
- 自動化 → スケジュール済みタスク
- タスクの種類「セグメント内の・・・」
- セグメント「All Players」
- 定期的 @weekly
- アクション CloudScript実行
一旦はタイトルデータに保管。名前を日付にするなどして上書きしないように
修正
2026/02/22 更新しました。主な内容は変わっていません。