この記事でのバージョン
Unity 2018.4.8f1
PlayFab SDK 2.77.191029
はじめに
今回はUnityでPlayFabを使ってユーザ名の更新とランキングの実装してみようという感じの記事です!
ちなみに、PlayFabとはなんぞや?という方は以下の記事を参照の事。
ざっくり言うとサーバーサイドが関わる事を楽して実装出来るサービスです。
しかも、無料で始める事も可能ですし、有料プランでも1000MAUまでは無料と
「ユーザが全然増えないのにお金だけ払う」みたいな事がありません。
なので個人開発でも使い始めやすいですし、Microsoftのサービスという安心感まであります。
Indie Plan、1,000 MAU まで無料だし、それを超えて有料になっても 100,000 MAU までは月額 $99 というお手頃価格なので個人や小規模なチームの開発にとても良いと思います🙂
— 南@エンジニア兼ティーアドバイザー (@_y_minami) 2019年11月14日
カジュアルなゲームなら機能制限がある代わりに MAU が何人でも完全無料の Essentials Plan でも良し☺️ https://t.co/TzPHB2g3ZR
なお、本記事は以下の導入やログイン処理が済んでいる前提になりますので、あしからず。
事前準備
まずランキングを実装する前にクライアントから情報を送信する許可を設定します。
その設定はWindow/PlayFab/Editor Extensionsで開けるウィンドウ右上の
GAME MANAGERをクリックすると開ける、ブラウザ上の設定用のページで行います。
設定箇所は左上の歯車のマークにある「タイトルの設定」を押した先にある
API機能の「クライアントにプレイヤー統計情報のポストを許可する」です。
ここにチェックを入れれば事前準備です。
ランキング作成
次にランキングの作成です。これも引き続きブラウザ上で行います。
作成場所は左側のランキングを選択した後にある「新しいランキング」ボタンです。
各設定を行った後、保存ボタンを押すと新しいランキングが作成される感じです。
なお、リセット頻度がランキングに登録されたスコアを初期化する頻度で、
(手動の場合は自動ではスコアは初期化されない)
集計方法がランキングの順位付けの方法の事になります。
ちなみに作成したランキングはブラウザ上でもランキングを確認可能ですし、
登録されているスコアを削除したり、ランキング自体を手動リセットする事も可能です。
ユーザ名の更新
PlayFabは各ユーザに名前を設定する事が出来るので、今度はその実装方法についての解説です。
なお、IDで識別出来るので名前を設定しなくてもランキングを利用する事は可能です。
肝心のユーザ名の更新方法ですが、
以前の記事で紹介したような感じでログイン処理を先に行います。
そしてその後、UpdateUserTitleDisplayNameRequestのインスタンスを生成し、
PlayFabClientAPI.UpdateUserTitleDisplayNameにそれプラス、成功時と失敗時のデリゲートを渡すだけ。
なお、新規で名前をつける時でも名前を変更する時でも同じ処理で問題ありません。
using System.Collections.Generic; using PlayFab; using PlayFab.ClientModels; using UnityEngine; using UnityEngine.UI; /// <summary> /// ランキングのサンプル /// </summary> public class RankingSample : MonoBehaviour { [SerializeField] private Text _nameText = default; //================================================================================= //ユーザ名 //================================================================================= /// <summary> /// ユーザ名を更新する /// </summary> public void UpdateUserName() { //ユーザ名を指定して、UpdateUserTitleDisplayNameRequestのインスタンスを生成 var request = new UpdateUserTitleDisplayNameRequest{ DisplayName = _nameText.text }; //ユーザ名の更新 Debug.Log($"ユーザ名の更新開始"); PlayFabClientAPI.UpdateUserTitleDisplayName(request, OnUpdateUserNameSuccess, OnUpdateUserNameFailure); } //ユーザ名の更新成功 private void OnUpdateUserNameSuccess(UpdateUserTitleDisplayNameResult result){ //result.DisplayNameに更新した後のユーザ名が入ってる Debug.Log($"ユーザ名の更新が成功しました : {result.DisplayName}"); } //ユーザ名の更新失敗 private void OnUpdateUserNameFailure(PlayFabError error){ Debug.LogError($"ユーザ名の更新に失敗しました\n{error.GenerateErrorReport()}"); } }
実際に使ってみると以下のような感じで、
名前を送信するとブラウザ上での表記が変わっているのが分かると思います。
ちなみに、名前が2文字以下だとエラーが出るようです。
スコア送信
スコアを送信し、ランキングに登録する方法ですが、
ユーザ名の更新と同様にログイン処理を先に行います。
そしてその後、StatisticUpdateという更新用のインスタンスを生成し、
それを使ってさらにUpdateUserDataRequestのインスタンスを生成、
最後にPlayFabClientAPI.UpdatePlayerStatisticsにそれプラス、成功時と失敗時のデリゲートを渡すだけ。
using System.Collections.Generic; using PlayFab; using PlayFab.ClientModels; using UnityEngine; using UnityEngine.UI; /// <summary> /// ランキングのサンプル /// </summary> public class RankingSample : MonoBehaviour { [SerializeField] private Text _scoreText = default; //================================================================================= //スコア //================================================================================= /// <summary> /// スコア(統計情報)を更新する /// </summary> public void UpdatePlayerStatistics() { //UpdatePlayerStatisticsRequestのインスタンスを生成 var request = new UpdatePlayerStatisticsRequest{ Statistics = new List<StatisticUpdate>{ new StatisticUpdate{ StatisticName = "ランキングサンプル", //ランキング名(統計情報名) Value = int.Parse( _scoreText.text), //スコア(int) } } }; //ユーザ名の更新 Debug.Log($"スコア(統計情報)の更新開始"); PlayFabClientAPI.UpdatePlayerStatistics(request, OnUpdatePlayerStatisticsSuccess, OnUpdatePlayerStatisticsFailure); } //スコア(統計情報)の更新成功 private void OnUpdatePlayerStatisticsSuccess(UpdatePlayerStatisticsResult result){ Debug.Log($"スコア(統計情報)の更新が成功しました"); } //スコア(統計情報)の更新失敗 private void OnUpdatePlayerStatisticsFailure(PlayFabError error){ Debug.LogError($"スコア(統計情報)更新に失敗しました\n{error.GenerateErrorReport()}"); } }
実際に使ってみると以下のような感じで、
送信したスコアがブラウザ上で表示されているのが分かると思います。
ランキング取得
ランキングの取得方法ですが、
他の処理と同様にログイン処理を先に行います。
そしてその後、GetLeaderboardRequestのインスタンスを生成し、
PlayFabClientAPI.GetLeaderboardにそれプラス、成功時と失敗時のデリゲートを渡すだけ。
using System.Collections.Generic; using PlayFab; using PlayFab.ClientModels; using UnityEngine; using UnityEngine.UI; /// <summary> /// ランキングのサンプル /// </summary> public class RankingSample : MonoBehaviour { [SerializeField] private Text _rankingText = default; //================================================================================= //ランキング取得 //================================================================================= /// <summary> /// ランキング(リーダーボード)を取得 /// </summary> public void GetLeaderboard() { //GetLeaderboardRequestのインスタンスを生成 var request = new GetLeaderboardRequest{ StatisticName = "ランキングサンプル", //ランキング名(統計情報名) StartPosition = 0, //何位以降のランキングを取得するか MaxResultsCount = 3 //ランキングデータを何件取得するか(最大100) }; //ランキング(リーダーボード)を取得 Debug.Log($"ランキング(リーダーボード)の取得開始"); PlayFabClientAPI.GetLeaderboard(request, OnGetLeaderboardSuccess, OnGetLeaderboardFailure); } //ランキング(リーダーボード)の取得成功 private void OnGetLeaderboardSuccess(GetLeaderboardResult result){ Debug.Log($"ランキング(リーダーボード)の取得に成功しました"); //result.Leaderboardに各順位の情報(PlayerLeaderboardEntry)が入っている _rankingText.text = ""; foreach (var entry in result.Leaderboard) { _rankingText.text += $"\n順位 : {entry.Position}, スコア : {entry.StatValue}, 名前 : {entry.DisplayName}, ID : {entry.PlayFabId}"; } } //ランキング(リーダーボード)の取得失敗 private void OnGetLeaderboardFailure(PlayFabError error){ Debug.LogError($"ランキング(リーダーボード)の取得に失敗しました\n{error.GenerateErrorReport()}"); } }
さきほどのスコア送信と併せて実際に使ってみると以下のような感じで、
指定した数だけ上位の順位が取得出来ている事が分かると思います。
なお、PlayFabClientAPI.GetLeaderboardAroundPlayerを使うことで、
自分周辺の順位を取得する事も可能です。
using System.Collections.Generic; using PlayFab; using PlayFab.ClientModels; using UnityEngine; using UnityEngine.UI; /// <summary> /// ランキングのサンプル /// </summary> public class RankingSample : MonoBehaviour { [SerializeField] private Text _rankingText = default; //================================================================================= //ランキング取得 //================================================================================= /// <summary> /// 自分の順位周辺のランキング(リーダーボード)を取得 /// </summary> public void GetLeaderboardAroundPlayer() { //GetLeaderboardAroundPlayerRequestのインスタンスを生成 var request = new GetLeaderboardAroundPlayerRequest{ StatisticName = "ランキングサンプル", //ランキング名(統計情報名) MaxResultsCount = 3 //自分を含め前後何件取得するか }; //自分の順位周辺のランキング(リーダーボード)を取得 Debug.Log($"自分の順位周辺のランキング(リーダーボード)の取得開始"); PlayFabClientAPI.GetLeaderboardAroundPlayer(request, OnGetLeaderboardAroundPlayerSuccess, OnGetLeaderboardAroundPlayerFailure); } //自分の順位周辺のランキング(リーダーボード)の取得成功 private void OnGetLeaderboardAroundPlayerSuccess(GetLeaderboardAroundPlayerResult result){ Debug.Log($"自分の順位周辺のランキング(リーダーボード)の取得に成功しました"); //result.Leaderboardに各順位の情報(PlayerLeaderboardEntry)が入っている _rankingText.text = ""; foreach (var entry in result.Leaderboard) { _rankingText.text += $"\n順位 : {entry.Position}, スコア : {entry.StatValue}, 名前 : {entry.DisplayName}, ID : {entry.PlayFabId}"; } } //自分の順位周辺のランキング(リーダーボード)の取得失敗 private void OnGetLeaderboardAroundPlayerFailure(PlayFabError error){ Debug.LogError($"自分の順位周辺のランキング(リーダーボード)の取得に失敗しました\n{error.GenerateErrorReport()}"); } }
おわりに
やはりランキングもびっくりするほど簡単に実装が行えました。
これを使えばiOSとAndroidなど別のプラットフォームで共通のランキングが
簡単に作れるので、マルチプラットフォームにリリースする際にはかなり魅力的だと思います。
ちなみにランキングの順位に応じて報酬を配布するという事も可能なようなので、
これについてもそのうち試して、記事にしたいと思います。
参考