使用Unity和PlayFab制作排行榜

2023-07-11  本文已影响0人  全新的饭

目标

各玩家可将成绩上传至排行榜,可查看排行榜

  1. 总排行榜中的信息:各玩家名次、昵称、得分


    image.png
  2. 玩家和玩家排名附近的其他玩家组成的排行榜(下文简称为玩家附近排行榜)信息


    image.png

实现思路

首先需要实现1个简单的账号系统,来标识各玩家。
排行榜相关的主要方法如下

  1. 向排行榜中上传成绩
  2. 拉取排行榜(总排行榜、玩家附近排行榜)

在Leaderboard.cs中实现这些内容。
注意:还需在PlayFab后台配置排行榜相关内容。具体可参考下文中排行榜相关的部分:游戏开发工具箱(3) 开箱即用的云游戏后端——PlayFab快速上手指南(上)

相关代码

Leaderboard.cs:排行榜相关的方法

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PlayFab;
using PlayFab.ClientModels;
using PlayFab.DataModels;

public class Leaderboard
{
    private const string Name = "My Test Score Leaderboard";
    private const int AllPlayerCnt = 5;
    private const int AroundPlayerCnt = 3;
    public Leaderboard()
    { }
    public void MyDestroy()
    {

    }

    // 提交成绩
    public void SubmitScore(int score)
    {
        var request = new PlayFab.ClientModels.UpdatePlayerStatisticsRequest
        {
            Statistics = new List<PlayFab.ClientModels.StatisticUpdate>
            {
                new PlayFab.ClientModels.StatisticUpdate
                {
                    StatisticName = Name,
                    Value = score
                }
            }
        };
        PlayFab.PlayFabClientAPI.UpdatePlayerStatistics(request, result =>
        {
            Debug.Log("向排行榜提交成绩:" + score);
        },
        error =>
        {
            Debug.LogError($"向排行榜提交成绩失败 == {error.GenerateErrorReport()}");
        });
    }
    // 获取总榜
    public void GetLeaderboard(Action<LeaderboardPlayerData[]> afterGetAction)
    {
        var request = new GetLeaderboardRequest
        {
            StatisticName = Name,
            StartPosition = 0,
            MaxResultsCount = AllPlayerCnt
        };

        PlayFabClientAPI.GetLeaderboard(request, result =>
        {
            List<LeaderboardPlayerData> leaderboardData = new List<LeaderboardPlayerData>();
            for (int i = 0; i < result.Leaderboard.Count; i++)
            {
                var curPlayer = result.Leaderboard[i];
                leaderboardData.Add(new LeaderboardPlayerData(curPlayer.Position + 1, curPlayer.PlayFabId, curPlayer.DisplayName, curPlayer.StatValue));
            }
            afterGetAction?.Invoke(leaderboardData.ToArray());
            Debug.Log("获取排行榜数据:" + leaderboardData.Count);
        },
        error =>
        {
            Debug.LogError($"获取排行榜数据失败 == {error.GenerateErrorReport()}");
        });
    }
    // 获取玩家周围榜
    public void GetLeaderboardAroundPlayer(Action<LeaderboardPlayerData[]> afterGetAction)
    {
        var request = new GetLeaderboardAroundPlayerRequest
        {
            StatisticName = Name,
            MaxResultsCount = AroundPlayerCnt
        };

        PlayFabClientAPI.GetLeaderboardAroundPlayer(request, result =>
        {
            List<LeaderboardPlayerData> leaderboardData = new List<LeaderboardPlayerData>();
            for (int i = 0; i < result.Leaderboard.Count; i++)
            {
                var curPlayer = result.Leaderboard[i];
                leaderboardData.Add(new LeaderboardPlayerData(curPlayer.Position + 1, curPlayer.PlayFabId, curPlayer.DisplayName, curPlayer.StatValue));
            }
            afterGetAction?.Invoke(leaderboardData.ToArray());
            Debug.Log("获取玩家周围榜数据:" + leaderboardData.Count);
        },
        error =>
        {
            Debug.LogError($"获取玩家周围榜数据失败 == {error.GenerateErrorReport()}");
        });
    }
}

public struct LeaderboardPlayerData
{
    public readonly int Ranking;
    public readonly string Id;
    public readonly string Name;
    public readonly int Score;
    public LeaderboardPlayerData(int ranking, string id, string name, int score)
    {
        Ranking = ranking;
        Id = id;
        Name = name;
        Score = score;
    }
}

LeaderboardView.cs:临时用于测试排行榜相关方法

using System.Text;
using System.Net.Mime;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class LeaderboardView : MonoBehaviour
{
    [SerializeField]
    private LoginSys _loginSys;
    private Leaderboard _leaderboard;

    private int _score;
    [SerializeField]
    private Text _scoreText;
    [SerializeField]
    private Text _leaderboardText;

    [SerializeField]
    private Button _generateScoreBtn;
    [SerializeField]
    private Button _submitScoreBtn;
    [SerializeField]
    private Button _showLeaderboardBtn;
    [SerializeField]
    private Button _showLeaderboardAroundPlayerBtn;
    [SerializeField]
    private Button _hideLeaderboardBtn;

    private void Start()
    {
        Init();
    }

    private void OnDestroy()
    {
        MyDestroy();
    }

    private void Init()
    {
        _leaderboard = new Leaderboard();
        GenerateScoreRandomly();

        _generateScoreBtn.onClick.AddListener(OnClickGenerateScoreBtn);
        _submitScoreBtn.onClick.AddListener(OnClickSubmitScoreBtn);
        _showLeaderboardBtn.onClick.AddListener(OnClickShowLeaderboardBtn);
        _showLeaderboardAroundPlayerBtn.onClick.AddListener(OnClickShowLeaderboardAroundPlayerBtn);
        _hideLeaderboardBtn.onClick.AddListener(OnClickHideLeaderboardBtn);
    }

    private void MyDestroy()
    {
        _leaderboard?.MyDestroy();
        _leaderboard = null;

        _generateScoreBtn?.onClick.RemoveListener(OnClickGenerateScoreBtn);
        _submitScoreBtn?.onClick.RemoveListener(OnClickSubmitScoreBtn);
        _showLeaderboardBtn?.onClick.RemoveListener(OnClickShowLeaderboardBtn);
        _showLeaderboardAroundPlayerBtn?.onClick.RemoveListener(OnClickShowLeaderboardAroundPlayerBtn);
        _hideLeaderboardBtn?.onClick.RemoveListener(OnClickHideLeaderboardBtn);
    }

    private void OnClickGenerateScoreBtn()
    {
        GenerateScoreRandomly();
    }
    private void OnClickSubmitScoreBtn()
    {
        SubmitScore();
    }
    private void OnClickShowLeaderboardBtn()
    {
        ShowLeaderboard();
    }
    private void OnClickShowLeaderboardAroundPlayerBtn()
    {
        ShowLeaderboardAroundPlayer();
    }
    private void OnClickHideLeaderboardBtn()
    {
        HideLeaderboard();
    }

    // 随机生成成绩
    private void GenerateScoreRandomly()
    {
        _score = UnityEngine.Random.Range(0, 100);
        _scoreText.text = _score.ToString();

    }
    // 提交成绩
    private void SubmitScore()
    {
        _leaderboard.SubmitScore(_score);
    }
    // 显示总榜
    private void ShowLeaderboard()
    {
        _leaderboard.GetLeaderboard(ShowLeaderboard);
    }
    // 显示周围榜
    private void ShowLeaderboardAroundPlayer()
    {
        _leaderboard.GetLeaderboardAroundPlayer(ShowLeaderboard);
    }
    // 隐藏排行榜
    private void HideLeaderboard()
    {
        ClearLeaderboard();
    }

    // 将榜单数据显示到Text上
    private string LeaderboardInfoToStr(LeaderboardPlayerData[] data)
    {
        StringBuilder sb = new StringBuilder();
        foreach (var d in data)
        {
            string preStr = IsMe(d.Id) ? "<color=yellow>" : string.Empty;
            string postStr = IsMe(d.Id) ? "</color>" : string.Empty;
            string content = $"{preStr}{d.Ranking}-{d.Name}-{d.Score}{postStr}";
            sb.AppendLine(content);
        }
        return sb.ToString();


        bool IsMe(string id)
        {
            return _loginSys.UserId == id;
        }
    }
    private void ShowLeaderboard(LeaderboardPlayerData[] data)
    {
        _leaderboardText.text = LeaderboardInfoToStr(data);
    }
    private void ClearLeaderboard()
    {
        _leaderboardText.text = string.Empty;
    }
}
上一篇下一篇

猜你喜欢

热点阅读