Unity集成Google Play游戏服务后如何获取玩家排行榜排名
How to Properly Retrieve Player Rank from Google Play Game Services in Unity
Hey there! Nice work getting your leaderboards up and running—let’s tweak your code to reliably fetch the player’s rank without hiccups. Here’s a step-by-step breakdown of what to adjust and a complete working implementation:
Key Fixes & Best Practices
- Verify Your Leaderboard ID: Make sure
myStringis an exact match for the leaderboard ID from your Google Play Console—typos here will break the whole process. - Add Error Handling: Always check if the score data returned has an error before accessing player scores to avoid crashes.
- Check for Null Player Scores: If the player hasn’t submitted a score to the leaderboard yet,
data.PlayerScorewill be null—we need to handle that case gracefully. - Update UI on the Main Thread: GPGS callbacks run on a background thread, so we have to dispatch UI updates to Unity’s main thread to prevent glitches.
Complete Working Code
Here’s a revised version of your method with all these safeguards in place:
using UnityEngine; using UnityEngine.UI; using GooglePlayGames; using GooglePlayGames.BasicApi; public static class LeaderboardHandler { public static Text RankTxt; // Assign this in the Inspector or via code public static void ShowLeaderboardsAndFetchRank() { // Replace with your actual leaderboard ID from Google Play Console string targetLeaderboardId = "YOUR_UNIQUE_LEADERBOARD_ID"; PlayGamesPlatform.Instance.LoadScores( targetLeaderboardId, LeaderboardStart.PlayerCentered, 100, LeaderboardCollection.Public, LeaderboardTimeSpan.AllTime, (LeaderboardScoreData scoreData) => { // First, check if there was an error loading scores if (scoreData.HasError) { Debug.LogError($"Failed to load leaderboard data: {scoreData.Error}"); // Update UI with error message (on main thread) MainThreadDispatcher.Instance.Enqueue(() => { RankTxt.text = "Error loading rank"; }); return; } // Check if the player has a score on this leaderboard if (scoreData.PlayerScore == null) { MainThreadDispatcher.Instance.Enqueue(() => { RankTxt.text = "No score submitted yet"; }); return; } // Successfully retrieved the player's rank int playerRank = scoreData.PlayerScore.rank; string leaderboardId = scoreData.Id; string playerId = scoreData.PlayerScore.userID; // Update the UI safely on the main thread MainThreadDispatcher.Instance.Enqueue(() => { RankTxt.text = $"Rank: {playerRank}\nLeaderboard ID: {leaderboardId}\nPlayer ID: {playerId}"; }); // Optional: Show the official leaderboard UI if needed PlayGamesPlatform.Instance.ShowLeaderboardUI(targetLeaderboardId); } ); } }
Quick Main Thread Dispatcher Setup
If you don’t have a way to run code on the main thread yet, create this simple helper script:
using System.Collections.Generic; using UnityEngine; public class MainThreadDispatcher : MonoBehaviour { public static MainThreadDispatcher Instance { get; private set; } private readonly Queue<System.Action> _pendingActions = new Queue<System.Action>(); private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); } else { Instance = this; DontDestroyOnLoad(gameObject); } } private void Update() { lock (_pendingActions) { while (_pendingActions.Count > 0) { _pendingActions.Dequeue().Invoke(); } } } public void Enqueue(System.Action action) { lock (_pendingActions) { _pendingActions.Enqueue(action); } } }
Just attach this script to an empty GameObject in your scene—it’ll handle routing UI updates to the main thread.
Final Checks
- Ensure the player is signed into Google Play Games before calling
ShowLeaderboardsAndFetchRank()(verify withPlayGamesPlatform.Instance.IsAuthenticated()). - Double-check that your leaderboard is published in the Google Play Console and the ID matches exactly what’s in your code.
内容的提问来源于stack exchange,提问作者weaverbeaver




