跳到主要内容
版本:v3

成就系统开发指南

本文介绍如何在游戏中加入成就系统。TDS 推出的成就系统模块,是基于内建账户系统(TDSUser)的,具体请阅读 内建账户 > 开发指南

环境要求

  • Unity 2019.4 或更高版本
  • iOS 11 或更高版本,Xcode 版本 14.1 或更高版本
  • Android 5.0(API level 21)或更高版本

权限说明

集成前准备

  1. 参考 准备工作 创建应用、开启成就服务、绑定 API 域名;

SDK 获取

由于成就服务依赖内建账户,所以集成游戏成就服务所需 SDK 依赖库需要在内建账户依赖库的基础上,在 下载页 获得 TapSDK,另外添加 TapAchievement 模块:

SDK 可以通过 Unity Package Manager 导入或手动导入,二者任选其一。请根据项目需要选择。

方法一:使用 Unity Package Manager

从 3.29.1 版本开始, SDK 修改 JSON 解析库为 Newtonsoft-json,如果当前工程已接入该依赖库,则不需额外处理,否则需在 Packages/manifest.json 添加如下依赖:

"com.unity.nuget.newtonsoft-json":"3.2.1"
NPMJS 安装

从 3.25.0 版本开始,TapSDK 支持了 NPMJS 安装,优势是只需要配置版本号,并且支持嵌套依赖。

在项目的 Packages/manifest.json 文件中添加以下依赖:

"dependencies":{
"com.taptap.tds.achievement":"3.29.4",
"com.taptap.tds.login":"3.29.4",
"com.taptap.tds.common":"3.29.4",
"com.taptap.tds.bootstrap":"3.29.4",
}

但需要注意的是,要在 Packages/manifest.jsondependencies 同级下声明 scopedRegistries

"scopedRegistries": [
{
"name": "NPMJS",
"url": "https://registry.npmjs.org/",
"scopes": ["com.tapsdk", "com.taptap", "com.leancloud"]
}
]

GitHub 安装

在项目的 Packages/manifest.json 文件中添加以下依赖:

"dependencies":{
"com.taptap.tds.login":"https://github.com/TapTap/TapLogin-Unity.git#3.29.4",
"com.taptap.tds.common":"https://github.com/TapTap/TapCommon-Unity.git#3.29.4",
"com.taptap.tds.bootstrap":"https://github.com/TapTap/TapBootstrap-Unity.git#3.29.4",
"com.taptap.tds.achievement":"https://github.com/TapTap/TapAchievement-Unity.git#3.29.4",
"com.leancloud.realtime":"https://github.com/leancloud/csharp-sdk-upm.git#realtime-2.3.0",
"com.leancloud.storage":"https://github.com/leancloud/csharp-sdk-upm.git#storage-2.3.0",
}

在 Unity 顶部菜单中选择 Window > Package Manager 可查看已经安装在项目中的包。

方法二:手动导入

  1. 下载页 找到 TapSDK Unity 下载地址,下载 TapSDK-UnityPackage.zip

  2. 在 Unity 项目中依次转到 Assets > Import Packages > Custom Packages,从解压后的 TapSDK-UnityPackage.zip 中,选择希望在游戏中使用的 TapSDK 包导入,其中:

    • TapTap_Bootstrap.unitypackage TapSDK 启动器,必选
    • TapTap_Common.unitypackage TapSDK 基础库,必选
    • TapTap_Login.unitypackage TapTap 登录库,必选
    • TapTap_Achievement.unitypackage TapTap 成就库,必选
  3. 如果当前项目已集成 Newtonsoft.Json 依赖,则忽略该步骤,否则在 NuGet.org Newtonsoft.Json 页面中通过点击右侧 「Download package」 下载库文件,并将下载的文件后缀从.nupkg 修改为 .zip,同时解压该文件并复制内部的 Newtonsoft.Json.dll 文件拷贝到工程 AssetsPlugins 目录下,另外为了避免导出 IL2CPP 平台时删除必要数据,需在 Assets 目录下创建 link.xml 文件(如果已有该文件,则添加如下内容),其内容如下:

<linker>
<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.Interpreter.LightLambda" preserve="all" />
</assembly>
</linker>

SDK 初始化

参考内建账户的初始化方法,初始化内建账户服务会同步初始化游戏成就服务;

模块基础设置

PC 平台的成就详情界面会显示游戏名称和游戏 Icon。(下图中:左上角图片为应用图标,「人类跌落梦境」为应用名称) img

默认情况下,SDK 会以应用的名字和图标来显示,如果需要自定义名字和图标,可以通过以下接口:

TapAchievement.SetApplicationName(string applicationName)

TapAchievement.SetApplicationIcon(Texture2D applicationIcon)

注册监听回调

成就 SDK 中包含多个监听回调,分别会在初始化数据成功、初始化数据失败以及成就进度更新时被调用,请特别注意初始化数据成功的回调,这是成就 SDK 正常使用的前提,初始化数据失败时请提示用户或者在合适的时候重新初始化数据。

使用前提

使用 TapTap.Achievement 前提是必须依赖 TapTap.Bootstrap 库。

命名空间

using TapTap.Achievement;

注册监听回调:

TapAchievement.RegisterCallback(IAchievementCallback callback);

private class AchievementCallback:IAchievementCallback
{
public void OnAchievementSDKInitSuccess()
{
// 成就 SDK 初始化成功
}

public void OnAchievementSDKInitFail(TapError errorCode)
{
if (errorCode != null)
{
// 初始化失败
}
}

public void OnAchievementStatusUpdate(TapAchievementBean bean, TapError errorCode)
{
if (errorCode != null)
{
// 成就状态更新失败
return;
}

if (bean != null)
{
// 成就状态更新成功
}
}
}

初始化数据

由于成就系统会在本地记录用户的成就数据,所以请在用户登录后初始化数据。如果用户切换账号时,务必重新调用该接口,不然数据可能会存在账号存储混乱的问题。

这个步骤是异步操作,需要确认收到成功回调时才能进行更多操作。

TapAchievement.InitData();

获取全部成就数据

全部成就数据分为本地数据和服务端数据两种:本地数据是记录在玩家本机的数据,本地数据会在调用初始化数据接口成功后被服务端数据刷新。主动调用服务端数据接口时也会更新本地数据。

如果在游玩过程中有更新服务端数据且需要实时更新的需求时,可以调用获取服务端数据接口来实现,正常情况下直接获取本地数据即可。

// 获取本地数据
TapAchievement.GetLocalAllAchievementList((list, code) =>
{
if (code != null)
{
// 获取成就数据失败
}
else
{
// 获取成就数据成功
});
}
// 获取服务器数据
TapAchievement.FetchAllAchievementList((list, code) =>
{
if (code != null)
{
// 获取成就数据失败
}
else
{
// 获取成就数据成功
});
}

获取当前用户成就数据

用户成就数据分为本地数据和服务端数据两种:本地数据是记录在玩家本机的数据,本地数据会在调用初始化数据接口成功后和服务端数据合并(对单个成就来说会以步长更高的数据为准)。主动调用服务端数据接口也会和本地数据进行合并。

对于用户数据,一般以本地数据为准。服务端数据可能存在上报失败等可能导致数据并非实时。

// 获取本地数据
TapAchievement.GetLocalUserAchievementList((list, code) =>
{
if (code != null)
{
// 获取成就数据失败
}
else
{
// 获取成就数据成功
});
}
// 获取服务器数据
TapAchievement.FetchUserAchievementList((list, code) =>
{
if (code != null)
{
// 获取成就数据失败
}
else
{
// 获取成就数据成功
});
}

达成某个成就(直接获得)

// displayID 是在开发者中心中添加成就时自行设定的 成就 ID
TapAchievement.Reach("displayID");

分步成就增长步数

成就增长步数提供两种方式调用,growSteps 中传递当前增量达成的步数(例如:多走了 5 步,则传递 5 即可),makeSteps 中传递当前成就已达成的步数(例如:当前已经走了 100 步,则传递 100),调用 growSteps 时 SDK 内部会计算当前全量步数。

// displayID 是在开发者中心中添加成就时自行设定的 成就 ID
TapAchievement.GrowSteps("displayID", step);
TapAchievement.MakeSteps("displayID", step);

设置冒泡开关

默认情况下,成就达成时 SDK 会自行展示一个冒泡浮窗提示玩家已达成相应成就。需要关闭请调用如下接口:

TapAchievement.SetShowToast(bool isShow);

打开成就展示页

SDK 自带一个展示所有成就和已达成成就情况的页面:

TapAchievement.ShowAchievementPage();

成就相关数据解读

public string displayId;              // 成就 ID 
public int visible = VisibleFalse; // 是否是隐藏成就
public string title; // 标题
public string subTitle; // 副标题
public string achieveIcon; // 图标
public int step; // 设定步数
public bool fullReached; // 是否达成
public int reachedStep; // 达成步数
public long reachedTime; // 达成时间
public AchievementStats stats; // 当前成就稀有度指标

国际化

成就支持设置语言:

提示

初始化数据时只会从服务端更新当前的语言对应的成就数据,如果在初始化后切换语言的话,需要重新调用 fetchAllAchievementListfetchUserAchievementList 接口来更新成就数据的多语言内容。

TapCommon.SetLanguage(TapLanguage.AUTO);

支持如下语言:

namespace TapTap.Common
{
public enum TapLanguage
{
AUTO = 0, // 自动
ZH_HANS = 1, // 简体中文
EN = 2, // 英文
ZH_HANT = 3, // 繁体中文
JA = 4, // 日文
KO = 5, // 韩文
TH = 6, // 泰文
ID = 7, // 印尼语
DE = 8, // 德语
ES = 9, // 西班牙语
FR = 10, // 法语
PT = 11, // 葡萄牙语
RU = 12, // 俄语
TR = 13, // 土耳其语
VI = 14, // 越南语
}
}

「自动」会尝试根据系统语言设置语言,如果系统语言不在上述支持的语言之中,那么会根据 SDK 初始化时配置的区域设置语言。 区域为中国大陆时会设置为简体中文,否则会设置为英文。

REST API

下面我们介绍成就相关的 REST API 接口。 开发者可以自行编写程序或脚本调用这些接口在服务端进行管理性质的操作。

请求格式

POST 请求的主体必须是 JSON 格式,而且 HTTP Header 的 Content-Type 需要设置为 application/json

请求的鉴权是通过 HTTP Header 里面包含的键值对来进行的,参数如下表:

KeyValue含义
X-TDS-Id{{clientId}}游戏的 Client Id,可在控制台查看
X-TDS-Server-Secret{{serverSecret}}游戏的 Server Secret,可在控制台查看

参见文档关于应用凭证的说明。

除了在 X-TDS-Id 这个 HTTP Header 中传入 Client Id 外,还需要在 URL 中指定 Client Id,两者的值需要一致。

获取成就的接口需要在 URL 中指定语言,详见语言代码列表

异常时返回 500(HTTP 状态码)错误,例如:

{
"code": "500",
"msg": "成就服务忙,稍后请求",
}

全部成就列表

获取游戏的全部成就,调用时需在 URL 中指定相应的语言。

curl -X GET \
-H "X-TDS-Id: {{clientId}}" \
-H "X-TDS-Server-Secret: {{serverSecret}}" \
https://tds-tapsdk.cn.tapapis.com/achievement/open/v1/clients/{{clientId}}/achievements/languages/<lang>

返回数据结构体:

{
"success": true,
"data": {
"list": [
{
"achievement_id": "成就 id",
"client_id": "应用 Client Id",
"achievement_open_id": "成就外部 id(开发者中心创建成就时自定义的成就 ID,向 SDK 上报成就的唯一标识)",
"achievement_type": "成就类型:1-普通成就,99-白金成就",
"is_hide": "是否隐藏:0-不隐藏,1-隐藏",
"count_step": "成就步数,不分步时是 1",
"show_order": "成就顺序,白金成就是 0",
"achievement_config_out_dto": {
"achievement_config_id": "成就配置 id",
"achievement_id": "成就 id",
"language_id": "语言 id",
"achievement_icon": "成就 icon 链接",
"achievement_title": "成就标题",
"achievement_sub_title": "成就副标题"
},
"achievement_rarity": {
"rarity": "稀有度比率",
"level": "稀有度:1-普通,2-稀有,3-珍贵,4-极为珍贵"
}
}
]
}
}

玩家成就列表

获取某一玩家取得的成就,调用时需在 URL 中指定该玩家对应的 TDS 内建账户的 ObjectId 和语言代码。

curl -X GET \
-H "X-TDS-Id: {{clientId}}" \
-H "X-TDS-Server-Secret: {{serverSecret}}" \
https://tds-tapsdk.cn.tapapis.com/achievement/open/v1/clients/{{clientId}}/users/<objectId>/achievements/languages/<lang>

返回数据结构体:

{
"success": true,
"data": {
"list": [
{
"achievement_id": "成就 id",
"client_id": "游戏 id",
"achievement_open_id": "成就外部 id(游戏在 DC 新增成就时绑定的 ID)",
"achievement_type": "成就类型:1-普通成就,99-白金成就",
"is_hide": "是否隐藏:0-不隐藏,1-隐藏",
"count_step": "成就步数,不分步时是 1",
"show_order": "成就顺序,白金成就是 0",
"achievement_config_out_dto": {
"achievement_config_id": "成就配置 id",
"achievement_id": "成就 id",
"language_id": "语言 id",
"achievement_icon": "成就 icon 链接",
"achievement_title": "成就标题",
"achievement_sub_title": "成就副标题"
},
"achievement_rarity": {
"rarity": "稀有度比率",
"level": "稀有度:1-普通,2-稀有,3-珍贵,4-极为珍贵"
},
"user_achievement_id": "用户成就 id",
"complete_time": "完成时间戳(毫秒级)",
"completed_step": "完成步数",
"full_completed": "是否完全完成,true-是,fasle-否"
}
]
}
}

提交成就

可以调用这一接口提交单个或多个玩家取得的成就,提交的成就会追加到玩家已达成的成就列表。

curl -X POST \
-H "X-TDS-Id: {{clientId}}" \
-H "X-TDS-Server-Secret: {{serverSecret}}" \
-H "Content-Type: application/json" \
-d '{"data": [{"user_id": <objectId>, "list":
[{
"achievement_id": "成就 id",
"achievement_open_id": "成就外部 id(开发者中心创建成就时自定义的成就 ID,向 SDK 上报成就的唯一标识)",
"complete_time": "完成时间戳(毫秒级)",
"completed_step": "完成步数"
}]
}]
}' \
https://tds-tapsdk.cn.tapapis.com/achievement/open/v1/clients/{{clientId}}/achievements

返回数据结构体:

{
"success": true,
"data": {
"list": [
{
"user_id": "ObjectId",
"result_list": [
{
"result": "本条数据上报是否成功,true 成功,false 失败",
"code": "成功时,返回 0,失败时,返回对应错误码",
"msg": "成功时,无返回,失败时,返回对应错误信息"
}
]
}
]
}
}

语言代码列表

使用 ISO 639-1 中定义的双小写字母语言代码(例如,en 表示英语,jp 表示日语),但:

  1. ISO 639-1 中未包括的语言,使用 ISO 632-2 中定义的三小写字母语言代码(例如,fil 表示菲律宾语)
  2. 仅使用语言代码无法表示所需语言时,附加 ISO 3166-1 中定义的地区代码(例如,zh_CN 表示简体中文)

当前 REST API 支持的语言代码如下:

代码语言
zh_CN简体中文
zh_TW繁体中文
en_US英语(美国)
ja_JP日文
ko_KR韩文
pt_PT葡萄牙语
vi_VN越南语
hi_IN印度语
id_ID印尼语
ms_MY马来语
th_TH泰语
es_ES西班牙语
af南非荷兰语
am阿姆哈拉语
bg保加利亚语
ca加泰罗尼亚语
hr克罗地亚语
cs捷克语
da丹麦语
nl荷兰语
et爱沙尼亚语
fil菲律宾语
fi芬兰语
fr法语
de德语
el希腊语
he希伯来语
hu匈牙利语
is冰岛语
it意大利语
lv拉脱维亚语
lt立陶宛语
no挪威语
pl波兰语
ro罗马尼亚语
ru俄语
sr塞尔维亚语
sk斯洛伐克语
sl斯洛文尼亚语
sw斯瓦希里语
sv瑞典语
tr土耳其语
uk乌克兰语
zu祖鲁语

注意,上表中的部分语言虽然 REST API 支持,但客户端 SDK 并没有支持

视频教程

可以参考视频教程:TapTap 成就功能讲解及接入,了解如何在 Untiy 项目中接入成就功能。

更多视频教程见开发者学堂。因为 SDK 功能在不断完善,视频教程可能出现与新版 SDK 功能不一致的地方,以当前文档为准。