Unity 遊戲中的排行榜

本主題說明如何在 Unity 遊戲中使用 Play 遊戲服務排行榜。

事前準備

設定 Unity 專案和 Unity 的 Google Play 遊戲外掛程式。詳情請參閱入門指南

建立活動

您可以在 Google Play 管理中心建立排行榜。詳情請參閱 Play 遊戲服務的排行榜指南。建立排行榜後,請按照入門指南中的說明,在外掛程式中加入排行榜的 Android 資源。

在排行榜上張貼得分

如要在排行榜上張貼得分,請呼叫 Social.ReportScore

    using GooglePlayGames;
    using UnityEngine.SocialPlatforms;
    ...
    // Post score 12345 to leaderboard ID "Cfji293fjsie_QA")
    Social.ReportScore(12345, "Cfji293fjsie_QA", (bool success) => {
        // Handle success or failure
    });

如要公布得分並加入中繼資料標記,請直接使用 PlayGamesPlatform 例項:

    using GooglePlayGames;
    using UnityEngine.SocialPlatforms;
    ...
    // Post score 12345 to leaderboard ID "Cfji293fjsie_QA" and tag "FirstDaily")
    PlayGamesPlatform.Instance.ReportScore(12345, "Cfji293fjsie_QA", "FirstDaily", (bool success) => {
        // Handle success or failure
    });

請注意,平台和伺服器會自動捨棄低於玩家現有最高分的分數,因此您可以自由提交分數,無需檢查分數是否高於玩家的現有分數。

顯示排行榜 UI

如要顯示所有排行榜的內建 UI,請呼叫 Social.ShowLeaderboardUI

    using GooglePlayGames;
    using UnityEngine.SocialPlatforms;
    ...
    // Show leaderboard UI
    Social.ShowLeaderboardUI();

如要顯示特定的排行榜,而非所有排行榜,您可以傳遞排行榜 ID 至該方法。但這是 Play 遊戲擴充功能,因此 Social.Active 物件必須先投放至 PlayGamesPlatform 物件:

    using GooglePlayGames;
    using UnityEngine.SocialPlatforms;
    ...
    // Show leaderboard UI
    PlayGamesPlatform.Instance.ShowLeaderboardUI("Cfji293fjsie_QA");

存取排行榜資料

有 2 種方法可以擷取排行榜分數資料。

使用 Social.ILeaderboard

此方法會使用 ILeaderboard 介面定義範圍,並篩選以取得資料。這個方法可讓您設定: 1. 排行榜 ID 2. 系列 (社交或公開) 3. 時間範圍 (每日、每週、不限時間) 4. 開始擷取分數的排名位置。 5. 得分記錄數 (預設值為 25)。 6. 依使用者 ID 篩選。

如果 from 參數為非正數,則傳回的結果將以玩家為中心,這表示系統會傳回接近目前玩家得分的分數。

    ILeaderboard lb = PlayGamesPlatform.Instance.CreateLeaderboard();
    lb.id = "MY_LEADERBOARD_ID";
    lb.LoadScores(ok =>
        {
            if (ok) {
                LoadUsersAndDisplay(lb);
            }
            else {
                Debug.Log("Error retrieving leaderboardi");
            }
        });

使用 PlayGamesPlatform.LoadScores()

這個方法直接使用 PlayGamesPlatform,可在存取排行榜資料時提供額外的彈性和資訊。

    PlayGamesPlatform.Instance.LoadScores(
            GPGSIds.leaderboard_leaders_in_smoketesting,
            LeaderboardStart.PlayerCentered,
            100,
            LeaderboardCollection.Public,
            LeaderboardTimeSpan.AllTime,
            (data) =>
            {
                mStatus = "Leaderboard data valid: " + data.Valid;
                mStatus += "\n approx:" +data.ApproximateCount + " have " + data.Scores.Length;
            });

LoadScores() 的參數如下:

  1. leaderboardId
  2. 起始位置 (最高得分或玩家置中)
  3. 資料列數
  4. 排行榜系列 (社交或公開)
  5. 時距 (每日、每週、不限時間)
  6. 回呼接受 LeaderboardScoreData 物件。

LeaderboardScoreData 類別可在載入得分時將資訊傳回呼叫端。包括: 1. ID - 排行榜 ID 2. Valid - 如果傳回的資料有效則為 true (呼叫成功) 3. Status - 呼叫的 ResponseStatus 4. ApproximateCount - 排行榜中的分數記錄約略數目 5. Title - 排行榜的標題 6. PlayerScore - 目前玩家的得分 7. Scores - 得分列表 8. PrevPageToken - 可用於呼叫 LoadMoreScores() 以取得上一頁得分的權杖。 9. NextPageToken - 用於呼叫 LoadMoreScores() 以取得下一頁得分的權杖。

    void GetNextPage(LeaderboardScoreData data)
    {
        PlayGamesPlatform.Instance.LoadMoreScores(data.NextPageToken, 10,
            (results) =>
            {
                mStatus = "Leaderboard data valid: " + data.Valid;
                mStatus += "\n approx:" +data.ApproximateCount + " have " + data.Scores.Length;
            });
    }

如果使用者並未予遊戲分享其好友名單,嘗試使用 ResponseCode.ResolutionRequired 載入好有時,此呼叫就可能會失敗。在這種情況下,請使用 AskForLoadFriendsResolution 以要求存取權。

取得玩家名稱

每個得分都有獲得該分數的玩家 ID。您可以使用 Social.LoadUsers() 載入玩家個人資料。提醒您,玩家個人資料的內容取決於玩家的隱私權設定。

    internal void LoadUsersAndDisplay(ILeaderboard lb)
    {
        // Get the user ids
        List<string> userIds = new List<string>();

        foreach(IScore score in lb.scores) {
            userIds.Add(score.userID);
        }
        // Load the profiles and display (or in this case, log)
        Social.LoadUsers(userIds.ToArray(), (users) =>
            {
                string status = "Leaderboard loading: " + lb.title + " count = " +
                    lb.scores.Length;
                foreach(IScore score in lb.scores) {
                    IUserProfile user = FindUser(users, score.userID);
                    status += "\n" + score.formattedValue + " by " +
                        (string)(
                            (user != null) ? user.userName : "**unk_" + score.userID + "**");
                }
                Debug.log(status);
            });
    }