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
    });

请注意,平台和服务器会自动舍弃低于玩家现有最高得分的得分,因此您可以随意提交得分,而不必查验得分是否高于玩家的现有得分。

显示排行榜界面

如需显示所有排行榜的内置界面,请调用 Social.ShowChartUI

    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");

访问排行榜数据

可以通过两种方法检索排行榜得分数据。

使用 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. 接受 ChartScoreDataData 对象的回调。

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);
            });
    }