排行榜
需求
需求:接入排行榜,每关都有单独的分数排行,在关卡结束后可点击弹出或主动弹出。
ps:没有做自己的服务器统计数据及好友关系等
解决方案一(嗯目前只有一)
UnityEngine.SocialPlatforms
UnityEngine.SocialPlatforms API点这里
Unity社交模型,集成了一些诸如好友,排行,成就等功能。
我这里只接入了iOS,所以以下只做iOS的分析
优点 | 使用方便,使用方便,使用方便,不用导入sdk什么的,Unity做了封装 |
缺点 | Unity做了封装,但有些api并不好用。另外,玩家只有开启GameCenter才能使用本功能。再另外,面板并不是很好看 |
o(╥﹏╥)o
默认情况下,在 iOS 上使用 GameCenter
。其他所有 平台均默认为可用于测试的本地实现,Android 一般用Google Play Games
。
iOS GameCenter
iOS GameCenter 能设置500个排行榜(并没有看到官方文档,据说有那么多),足够用了。
AppStoreConnect配置
![](https://i-blog.csdnimg.cn/blog_migrate/57ae5607f5709c2abc6bec3cf2a2c59f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7c62870b5bf1956723fda9e9c57f3b75.png)
![](https://i-blog.csdnimg.cn/blog_migrate/dafb7beffb57a9e91d302d90cb1da64a.png)
重复以上步骤,需要几个排行榜加几个,暂时没找到批量的方法
Unity 调用(如果使用GameCenter系统的面板,看到这里就可以了)
using UnityEngine;
using UnityEngine.SocialPlatforms;
namespace HZH
{
public class RankingList
{
private static RankingList _instance;
public RankingList Instance => _instance??new RankingList();
public void Init ()
{
if (Application.platform == RuntimePlatform.IPhonePlayer) {
Social.localUser.Authenticate (success =>
{
Debug.Log(success ? "GameCenter初始化成功" : "GameCenter初始化失败");
});
}
}
/// <summary>
/// 上传数据
/// </summary>
/// <param name="score">分数</param>
/// <param name="leaderboardID">指定的排行榜id</param>
public void ReportScore (long score, string leaderboardID)
{
if (Application.platform != RuntimePlatform.IPhonePlayer) return;
if (Social.localUser.authenticated) {
Social.ReportScore (score, leaderboardID, success =>
{
Debug.Log(success
? $"GameCenter:{leaderboardID}分数{score}上报成功"
: $"GameCenter:{leaderboardID}分数{score}上报失败");
});
}
}
/// <summary>
/// 拉起排行榜数据
/// </summary>
public void ShowLeaderboard ()
{
if (Application.platform != RuntimePlatform.IPhonePlayer) return;
if (!Social.localUser.authenticated) return;
Social.ShowLeaderboardUI ();
}
/// <summary>
/// 获取指定排行榜数据
/// </summary>
/// <param name="boardId"></param>
public void GetBoardData(string boardId)
{
if (Application.platform != RuntimePlatform.IPhonePlayer) return;
ILeaderboard leaderboard = Social.CreateLeaderboard();
leaderboard.id = boardId;
leaderboard.LoadScores(result =>
{
Debug.Log("Received " + leaderboard.scores.Length + " scores");
foreach (IScore score in leaderboard.scores)
Debug.Log(score);
});
}
}
}
如果团队愿意用Native的GameCenter排行榜界面,这里ShowLeaderboard
已经能完成了。初始化,数据上报,拉取排行榜面板。
面板在不同机型上显示也不一样,以下是一种机型作参考
坑(需要获取数据做自定义面板的看这里)
如果native面板不满足需求,就需要拿到排行榜数据,自己做实现。
上面的代码GetBoardData
方法并不能正确获取到玩家昵称数据。测试2个账号,一个昵称显示未知,一个获取数据失败。账号所限,没办法测试更多了。
这里我找到的解决方案是在iOS直接调用Native的api获取数据
iOS代码
GameCenterCtrl.h
@interface GameCenterCtrl : NSObject // 声明需要的字段
{
}
-(void)GetRankingListData:(const char*)boardId;
@end
GameCenterCtrl.m
#import <Foundation/Foundation.h>
#import <GameKit/GameKit.h>
#import "GameCenterCtrl.h"
@implementation GameCenterCtrl
-(id)init {
return self;
}
-(void) GetRankingListData:(const char*)boardId{
GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
if (leaderboardRequest != nil)
{
NSString* board = [[NSString alloc] initWithUTF8String:boardId];
leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;
leaderboardRequest.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardRequest.range = NSMakeRange(1,10);
leaderboardRequest.identifier = board;
[leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) {
if (error != nil){
// handle the error.
NSLog(@"下载失败@");
NSLog(@"%@", error);
}
if (scores != nil){
// process the score information.
NSLog(@"下载成功....");
NSArray *tempScore = [NSArray arrayWithArray:leaderboardRequest.scores];
NSMutableArray* array = [NSMutableArray arrayWithCapacity:tempScore.count];
for (GKScore *obj in tempScore) {
GKPlayer *player = obj.player;
NSString *point = [NSString stringWithFormat:@"%lld", obj.value];
NSString *rank = [NSString stringWithFormat:@"%ld", obj.rank];
NSDictionary *dict = @{
@"name":player.alias,
@"point":point,
@"rank":rank,
};
[array addObject:dict];
}
NSData *data = [NSJSONSerialization dataWithJSONObject:array options:kNilOptions error:nil];
NSLog(@"u3d_packageJosn data: %@", data);
// nsdata -> nsstring
NSString *jsonString = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"u3d_packageJosn jsonString: %@", jsonString);
// nsstring -> const char*
const char* constStr = [jsonString UTF8String];
UnitySendMessage(你的GameObject名字, 接收数据的方法名, constStr);
}
}];
}
}
@end
PortFile.h
#import <Foundation/Foundation.h>
@interface PortFile : NSObject
void GetRankingListData(const char* boardId);
@end
PortFile.m
#import "PortFile.h"
#import "GameCenterCtrl.h"
// 这个对象用来接收Unity信息,处理OC代码
void showAppStoreScoreView(){
[[GameCenterCtrl alloc]GetRankingListData:boardId];
}
以上4个文件放到Assets/Plugins/ios
文件夹下,GameCenterCtrl也可以直接按PortFile的写法,省了portFile俩文件。 或者用自己的unity2iOS通信方案,核心就GameCenterCtrl.m
的GetRankingListData
方法。
Unity 代码
获取数据
[DllImport("__Internal")]
private static extern void GetRankingListData(string boardId);
public void GetRankingData(string boardId){
GetRankingListData(boardId)
}
接收数据(数据获取是异步进行的,所以用的UnitySendMessage),这个Unity接收数据想来都懂,就不一步步写了。拿到数据json解一下就可以为所欲为了
吐槽
搜索Unity排行榜,帖子茫茫多,全是教怎么写界面的,写界面用你教呀 -_-||