You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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 myString is 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.PlayerScore will 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 with PlayGamesPlatform.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

火山引擎 最新活动