使用Unity和PlayFab制作排行榜
2023-07-11 本文已影响0人
全新的饭
目标
各玩家可将成绩上传至排行榜,可查看排行榜
-
总排行榜中的信息:各玩家名次、昵称、得分
image.png
-
玩家和玩家排名附近的其他玩家组成的排行榜(下文简称为玩家附近排行榜)信息
image.png
实现思路
首先需要实现1个简单的账号系统,来标识各玩家。
排行榜相关的主要方法如下
- 向排行榜中上传成绩
- 拉取排行榜(总排行榜、玩家附近排行榜)
在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;
}
}