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

访问排行榜数据

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

使用 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. start position (起始位置)(最高分或以玩家为中心)
  3. row count (行数)
  4. leaderboard collection (排行榜集合)(社交或公开)
  5. time span (时间范围)(每日、每周、所有时间)
  6. callback accepting a LeaderboardScoreData object. (接受 LeaderboardScoreData 对象的 callback。)

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