Unity集成Google Play Services排行榜排名-1、部分测试者登录异常
Unity 接入 Google Play Games 异常排查方案
问题清单
- 部分测试者无法正常登录 Google Play,其余测试者登录功能正常
- 部分测试账号加载排行榜时,自身排名返回值为
-1,无法通过后台手动修改数据,现有代码已做未登录用户不上传分数的前置校验
一、部分账号登录失败排查路径
- 检查测试名单配置:Google Play Console 中必须同时将测试账号加入「应用测试列表」和「Play Games 服务测试者列表」,漏配任意列表都会导致登录失败,且报错不会明确提示权限问题;如果是封闭测试轨道发布的包,测试账号必须先点击接受测试邀请链接,否则即使在名单内也会被拦截。
- 检查签名一致性:本地打包使用的 keystore、上传到 Google Play 的签名证书指纹,必须和 Play Games 后台配置的 OAuth2 客户端指纹完全匹配。如果测试者安装的是本地调试包、第三方渠道重签包,签名不匹配会直接导致登录失败。
- 检查设备环境:登录失败的设备必须安装正版 Google Play 服务、Google Play 商店基础框架,且账号所属地区支持 Play Games 服务;如果设备网络拦截了 Google 服务请求、Google Play 服务版本过低,也会出现偶发登录失败,可通过抓包确认认证请求是否正常发出定位问题。如果测试账号是企业配发的 G Suite 管理账号,管理员关闭 Play Games 权限的话也无法登录,这类情况更换普通个人 Gmail 账号测试即可。
- 修正现有代码逻辑缺陷:当前代码在
Start方法中依赖本地缓存的IsConnected状态判断连接情况,如果用户在系统层面退出了 Google 账号,本地缓存状态和实际登录态不一致,直接触发认证很容易失败。建议每次启动游戏触发认证时先清空本地缓存的连接标记,完全以 SDK 返回的认证结果为准。
二、排行榜排名返回 -1 排查与修复
IScore.rank 返回 -1 是 GPGS SDK 定义的标准返回值,不是后台脏数据,不需要修改排行榜配置、不需要操作后台数据,对应触发场景和修复方式如下:
- 服务端排序延迟:分数上报后 Play Games 服务端不是实时完成排序计算,新上报的分数通常有1~10分钟的计算窗口,窗口内拉取排行榜就会返回
-1,等待服务端计算完成后会自动返回正常排名,无需人工干预。 - 拉取参数组合问题:当前代码调用
LoadScores时使用LeaderboardStart.TopScores参数拉取前10名分数,如果当前玩家分数没有进入拉取的Top榜单范围,部分版本的 GPGS 插件不会返回榜单外用户的排名信息,直接返回-1。不需要新建排行榜,只要在拉取Top榜单之外,额外发起一次以玩家为中心的分数拉取请求,就能拿到准确的个人排名。 - 账号隐私设置限制:如果测试账号在 Play Games 设置中开启了「不公开游戏活动」「不在公开排行榜展示」选项,拉取公开排行榜集合时就无法获取该用户的公开排名,返回
-1。这类情况让测试者打开 Play Games 的隐私设置,将对应游戏的活动可见性调整为公开或好友可见即可。 - 修正现有代码逻辑漏洞:当前代码把
LeaderboardDataHasFilled标记设为true的时机是发起LoadScores请求之后,而不是请求回调成功之后,一旦第一次加载因为网络问题失败,后续打开排行榜会直接跳过加载逻辑,永远显示异常值。需要把这个标记的赋值移到加载回调内部,加载成功再标记为已填充,加载失败时重置标记允许下次重试。另外当前代码在PlayerScoreSetup和DisplayLeaderboardEntries方法中直接取profiles[0]没有做长度校验,如果Social.LoadUsers因为网络问题返回空数组会直接触发空引用崩溃,需要补充数组长度判断,数据异常时显示加载失败提示即可。
关键代码调整参考
1. 修正排行榜标记位逻辑
PlayGamesPlatform.Instance.LoadScores( GPGSIds.leaderboard_newtya, LeaderboardStart.TopScores, 10, LeaderboardCollection.Public, LeaderboardTimeSpan.AllTime, (data) => { if (data == null) { LeaderboardDataHasFilled = false; // 加载失败允许后续重试 Debug.LogError("Data Was Null"); return; } // 原有榜单数据处理逻辑不变 LeaderboardDataHasFilled = true; // 加载完成后再标记已填充 }); // 注意:删除原LoadScores调用后直接写的LeaderboardDataHasFilled = true;
2. 补充玩家自身排名拉取逻辑
// 在原有Top榜单拉取逻辑外,额外拉取一次玩家自身的准确排名 PlayGamesPlatform.Instance.LoadScores( GPGSIds.leaderboard_newtya, LeaderboardStart.PlayerCentered, 1, LeaderboardCollection.Public, LeaderboardTimeSpan.AllTime, (playerData) => { if (playerData.PlayerScore != null && playerData.PlayerScore.rank > 0) { PlayerRank.text = playerData.PlayerScore.rank.ToString(); } else { PlayerRank.text = "排名同步中"; } });
内容的提问来源于stack exchange,提问作者Spoiled Unknown
相关产品推荐
相关产品推荐

