Unity SDK 开发指南
本文介绍如何在游戏中加入排行榜系统。
集成前准备
- 参考 开发者中心配置 创建应用、配置包名与签名证书
- 参考 Unity 集成指南 完成基础接入
- 排行榜模块依赖于 TapTap 登录模块,开发者接入前应先完成 TapTap 登录的接入
权限说明
Android 权限说明
该模块在 Android 平台需要如下权限:
| 权限 | 使用目的 | 权限申请时机 |
|---|---|---|
| 网络权限 | 用于访问网络数据 | 用户首次使用该功能时会申请权限 |
| 网络状态权限 | 用于检查网络连接状态(如 Wi-Fi 或移动数据是否可用) | 用户首次使用该功能时会申请权限 |
| 写入外部存储权限 | 用于保存排行榜分享图片到设备存储 | 用户首次使用分享功能时会申请权限 |
该模块将在 Android 应用中添加如下权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
iOS 权限说明
该模块在 iOS 平台需要如下权限:
| 权限 | 使用目的 | 权限申请时机 |
|---|---|---|
| 相册权限 | 保存图片到相册 | 用户首次使用该功能时会申请权限 |
在 Assets/Plugins/iOS/Resource 目录下创建 TDS-Info.plist 文件(如果已创建,只需添加内容即可),配置相关权限并替换授权文案:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问相册以保存图片</string>
</dict>
</plist>
SDK 获取
远程依赖
NPMJS 方式:在 Packages/manifest.json 中添加:
"dependencies":{
"com.taptap.sdk.core":"4.11.0",
"com.taptap.sdk.login":"4.11.0",
"com.taptap.sdk.leaderboard":"4.11.0"
}
GitHub 方式:在 Packages/manifest.json 中添加:
"dependencies":{
"com.taptap.sdk.core":"https://github.com/taptap/tapsdk-unity-dist.git?path=/Core#4.11.0",
"com.taptap.sdk.login":"https://github.com/taptap/tapsdk-unity-dist.git?path=/Login#4.11.0",
"com.taptap.sdk.leaderboard":"https://github.com/taptap/tapsdk-unity-dist.git?path=/Leaderboard#4.11.0"
}
本地文件导入
在 下载页 下载并导入以下 unitypackage 文件:
TapSDK_Core.unitypackage(TapTapSDK 核心模块,必选)TapSDK_Login.unitypackage(TapTapSDK 登录模块,必选)TapSDK_Leaderboard.unitypackage(TapTapSDK 排行榜模块,必选)
注册排行榜事件回调
排行榜 SDK 提供事件回调接口,用于处理排行榜相关事件,如用户未登录等状态。
using TapSDK.Leaderboard;
LeaderboardCallback callback = new LeaderboardCallback();
TapTapLeaderboard.RegisterLeaderboardCallback(callback);
TapTapLeaderboard.UnregisterLeaderboardCallback(callback);
class LeaderboardCallback : ITapTapLeaderboardCallback
{
public LeaderboardCallback(){}
public void OnLeaderboardResult(int code, string message)
{
// 处理排行榜 SDK 的状态码
// 500102:需要登录
}
}
设置分享功能
设置分享回调后,排行榜H5页面会显示分享按钮,用户点击分享按钮后,排行榜截图会保存到本地,并触发分享成功回调。开发者可以根据自己的需要判断是否实现分享失败的回调方法。
using TapSDK.Leaderboard;
using UnityEngine;
// 设置分享回调(同步方法,建议在初始化后调用)
public void SetupLeaderboardSharing()
{
var shareCallback = new TapTapLeaderboardShareCallback
{
OnShareSuccessAction = (localPath) =>
{
// 处理排行榜分享图片保存成功
// localPath 为本地图片路径,可用于分享到系统
Debug.Log($"Share image saved to: {localPath}");
// 可以在这里调用系统分享功能
ShareImageToSystem(localPath);
},
OnShareFailedAction = (error) =>
{
// 处理分享失败(可选实现)
// 开发者可以根据需要选择是否实现此方法
Debug.LogError($"Share failed: {error?.Message}");
}
};
TapTapLeaderboard.SetShareCallback(shareCallback);
Debug.Log("Leaderboard share callback has been set");
}
// 分享图片到系统的示例方法
private void ShareImageToSystem(string imagePath)
{
// 这里可以实现具体的系统分享逻辑
// 例如使用Native Share 插件或 Unity 的分享功能,
// 当需要通过 getUriForFile 方式获取对应文件 uri 时,authority 为 当前包名 + ".tapsdk.leaderboard.fileprovider"
Debug.Log($"Sharing image: {imagePath}");
}
打开排行榜页面
打开排行榜H5页面对话框,支持总榜和好友榜两种类型。
tip
如果排行榜页面显示不完整、按钮被遮挡或布局方向异常,请先确认 TapSDK 初始化时的 screenOrientation 参数是否与游戏实际屏幕方向一致。
using TapSDK.Leaderboard;
// 打开排行榜页面(同步方法,无需async)
public void OpenLeaderboardPanel()
{
string leaderboardId = "your_leaderboard_id";
// 打开总榜
TapTapLeaderboard.OpenLeaderboard(leaderboardId, "public");
// 打开好友榜
TapTapLeaderboard.OpenLeaderboard(leaderboardId, "friends");
}
// 根据条件动态打开不同类型的排行榜
public void OpenLeaderboardByType(bool isFriendsBoard)
{
string leaderboardId = "your_leaderboard_id";
string collection = isFriendsBoard ? "friends" : "public";
TapTapLeaderboard.OpenLeaderboard(leaderboardId, collection);
}
打开用户个人资料
展示指定用户的个人资料对话框,传入用户的openId。
using TapSDK.Leaderboard;
// 打开用户个人资料(使用OpenID)
string openId = "user_open_id"; // 用户的OpenID
TapTapLeaderboard.ShowTapUserProfile(openId, null);
// 或者使用UnionID
string unionId = "user_union_id"; // 用户的UnionID
TapTapLeaderboard.ShowTapUserProfile(string.Empty, unionId);
提交分数
批量提交用户排行榜分数,一次最多提交5个分数。
using System.Collections.Generic;
using TapSDK.Leaderboard;
using UnityEngine;
// 提交分数(异步方法,需要在async方法中调用)
public async void SubmitPlayerScores()
{
// 单个分数提交
var singleScore = new List<SubmitScoresRequest.ScoreItem>
{
new SubmitScoresRequest.ScoreItem
{
LeaderboardId = "your_leaderboard_id",
Score = 1000
}
};
// 提交分数(使用异步方式)
try
{
var result = await TapTapLeaderboard.SubmitScores(singleScore);
// 提交成功
Debug.Log($"Submit scores success: {result}");
}
catch (TapException e)
{
// 提交失败
Debug.LogError($"Submit scores failed, code: {e.code}, message: {e.message}");
}
}
// 或者在需要时批量提交多个分数
public async void SubmitMultipleScores()
{
var multipleScores = new List<SubmitScoresRequest.ScoreItem>
{
new SubmitScoresRequest.ScoreItem
{
LeaderboardId = "leaderboard_1",
Score = 1000
},
new SubmitScoresRequest.ScoreItem
{
LeaderboardId = "leaderboard_2",
Score = 2000
}
};
try
{
var result = await TapTapLeaderboard.SubmitScores(multipleScores);
Debug.Log($"Submit multiple scores success: {result}");
}
catch (TapException e)
{
Debug.LogError($"Submit multiple scores failed, code: {e.code}, message: {e.message}");
}
}
获取排行榜数据
分页获取排行榜数据,支持总榜和好友榜。
using TapSDK.Leaderboard;
using UnityEngine;
// 获取排行榜数据(异步方法,需要在async方法中调用)
public async void LoadLeaderboardData()
{
string leaderboardId = "your_leaderboard_id";
string leaderboardCollection = "public"; // 总榜:"public",好友榜:"friends"
string nextPageToken = null; // 首次请求传null,加载更多时传上次请求返回的nextPage
string periodToken = null; // 时间周期标识,传null使用当前周期
try
{
var scores = await TapTapLeaderboard.LoadLeaderboardScores(
leaderboardId,
leaderboardCollection,
nextPageToken,
periodToken);
// 获取成功
if (scores != null)
{
// 保存分页标识用于加载更多数据
nextPageToken = scores.nextPage;
// 处理分数数据
if (scores.scores != null && scores.scores.Count > 0)
{
Debug.Log($"Loaded {scores.scores.Count} scores");
// 遍历排行榜数据
for (int i = 0; i < scores.scores.Count; i++)
{
var score = scores.scores[i];
Debug.Log($"Rank {score.rank}: {score.user?.name} - Score: {score.score}");
}
}
else
{
Debug.Log("No scores found for this leaderboard");
}
}
}
catch (TapException e)
{
// 获取失败,根据错误码进行处理
Debug.LogError($"Load leaderboard scores failed, code: {e.code}, message: {e.message}");
// 可以根据错误码进行特殊处理
if (e.code == 500102)
{
// 用户未登录,引导登录
Debug.LogWarning("User not logged in, please login first");
}
}
}
获取当前用户分数
获取当前登录用户在指定排行榜的分数和排名。
using TapSDK.Leaderboard;
using UnityEngine;
// 获取当前用户分数(异步方法,需要在async方法中调用)
public async void LoadCurrentPlayerScore()
{
string leaderboardId = "your_leaderboard_id";
string leaderboardCollection = "public"; // 总榜,使用"friends"获取好友榜
string periodToken = null; // 时间周期标识,默认为当前周期
try
{
var result = await TapTapLeaderboard.LoadCurrentPlayerLeaderboardScore(
leaderboardId,
leaderboardCollection,
periodToken);
// 获取成功
if (result.currentUserScore != null)
{
var userScore = result.currentUserScore;
Debug.Log($"Current player score: {userScore.score}, rank: {userScore.rank}");
// 处理用户分数和排名
}
else
{
Debug.Log("User has no score on this leaderboard");
}
}
catch (TapException e)
{
// 获取失败
Debug.LogError($"Load current player score failed, code: {e.code}, message: {e.message}");
}
}
获取用户相近分数
查询当前用户相近的其他用户成绩(上下X位)。
using TapSDK.Leaderboard;
using UnityEngine;
// 获取用户相近分数(异步方法,需要在async方法中调用)
public async void LoadPlayerCenteredScores()
{
string leaderboardId = "your_leaderboard_id";
string leaderboardCollection = "friends"; // 好友榜
string periodToken = "weekly"; // 时间周期标识
int maxCount = 10; // 最大返回数量
try
{
var result = await TapTapLeaderboard.LoadPlayerCenteredScores(
leaderboardId,
leaderboardCollection,
periodToken,
maxCount);
// 获取成功
if (result.scores != null)
{
Debug.Log($"Loaded {result.scores.Count} player centered scores");
// 处理相近用户分数数据
foreach (var score in result.scores)
{
Debug.Log($"Player: {score.user.name}, Score: {score.score}, Rank: {score.rank}");
}
}
}
catch (TapException e)
{
// 获取失败
Debug.LogError($"Load player centered scores failed, code: {e.code}, message: {e.message}");
}
}
错误处理
排行榜 SDK 的所有异步操作都通过 TapTapLeaderboardResponseCallback 返回结果,开发者需要在 onFailure 方法中处理错误情况。
错误码说明
| 错误码 | 错误类型 | 描述 |
|---|---|---|
| 500000 | 排行榜周期已过期 | 提示用户排行榜周期已结束,引导查看其他周期 |
| 500001 | 排行榜 ID 未找到 | 检查排行榜ID是否正确,提示用户排行榜不存在 |
| 500002 | 排行榜参数错误 | leaderboard_id 与 client_id 不匹配 |
| 500101 | 当前用户未授权获取此产品(服务) | 提示用户权限不足,联系管理员 |
| 500102 | 用户未登录 | 引导用户登录 |
| 500199 | 未知错误 | 通用错误处理,建议重试或联系技术支持 |
错误处理示例
using TapSDK.Leaderboard;
using UnityEngine;
// 示例:获取排行榜数据并处理错误(异步方法,需要在async方法中调用)
public async void LoadLeaderboardWithErrorHandling()
{
try
{
var data = await TapTapLeaderboard.LoadLeaderboardScores(
"your_leaderboard_id",
"public",
null,
null);
// 处理成功结果
Debug.Log($"Successfully loaded {data.scores?.Count ?? 0} scores");
}
catch (TapException e)
{
// 根据错误码处理不同的错误情况
switch (e.code)
{
case 500000:
// 排行榜周期已过期
Debug.LogWarning("排行榜周期已结束,请查看其他周期排行榜");
break;
case 500001:
// 排行榜 ID 未找到
Debug.LogError("排行榜不存在,请检查排行榜ID");
break;
case 500002:
// 排行榜参数错误
Debug.LogError("参数错误,请检查输入参数");
break;
case 500101:
// 用户未授权
Debug.LogError("权限不足,请联系管理员");
break;
case 500102:
// 用户未登录
Debug.LogWarning("用户未登录,需要引导用户登录");
// ShowLoginDialog();
break;
case 500199:
// 未知错误
Debug.LogError("未知错误,请稍后重试");
break;
default:
// 其他错误
Debug.LogError($"操作失败: {e.message}");
break;
}
}
}