Unity 游戏中的排行榜

本主题介绍如何在 Unity 游戏中使用 Play 游戏服务排行榜。

开始之前

设置您的 Unity 项目和 Google Play 游戏 Unity 插件。详情请参阅入门指南

创建事件

您可以在 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");

访问排行榜数据

有两种方法可以检索排行榜分数数据。

使用 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. 排行榜 ID
  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 请求访问权限。

获取玩家姓名

每个分数都有获得该分数的玩家的 userId。您可以使用 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);
            });
    }