开发

成就

更新时间: 2026年4月17日
Notice of feature support change
玩家成绩应用自 2024 年 12 月 20 日起已正式停用。此更改不会破坏使用 Achievements API 的现有应用。
This is a Platform SDK feature requiring Data Use Checkup
使用此功能或其他任何平台 SDK 功能之前,您需要完成数据使用情况检查 (DUC)。DUC 可确保您遵守开发者政策。这需要你团队的管理员证明你对用户数据的使用符合平台守则。在应用审核团队审核并批准您的 DUC 之前,平台功能仅供测试用户使用。
Apps for children can't use Platform SDK features
如果您自我证明您的应用主要用于未满 13 岁的儿童,则必须避免使用平台 SDK 功能。这一限制确保遵守特定于年龄的守则。为确保合规性,已为您的应用禁用数据使用情况检查。
创建奖杯、徽章、奖励等,激励用户实现目标。用户可以看到好友已取得的成就,从而在好友之间形成竞争。在您的应用中取得的成就也可以显示在 Meta Quest 主控室中,以显示用户在游戏中的进度和进展情况。本指南向您展示了如何定义全局成就、SDK 方法、您可以执行的用来与成就服务互动的服务器到服务器调用,以及您可以查看的实施示例。
Meta Horizon 平台追踪和管理成就。解锁成就时,平台会显示祝酒通知并播放声音。您的应用管理成就的触发器和更新,并向用户显示成就。

创建成就

向您的游戏添加成就的第一步是定义成就及其解锁方式。要创建成就,请遵循以下步骤。
  1. 导航至开发者面板 > 互动 > 成就
  2. 选择创建成就并输入以下信息:
    • API 名称 - 您用来引用应用中的成就的唯一字符串。API 名称区分大小写,您在面板中定义的名称必须与您在代码中引用的名称完全匹配。
    • 本地化和管理语言 -(可选)创建成就时,您可以选择将成就本地化为多种语言。输入成就信息时,选择管理语言,勾选您要本地化的目标语言旁边的方框,然后为选择的语言输入信息。向用户显示的语言是基于用户设备操作系统的语言设置。
      User Data Warning
      避免使用任何个人身份识别信息。
    • 标题 - 用户将看到的简短的描述性名称。
    • 描述 - 对成就的完整描述。您可能想描述用户是如何解锁或取得这项成就的。
    • 解锁描述(可选) - 这个描述将在用户解锁成就后替换之前的描述。
    • 锁定和解锁的图标(可选) - 与成就关联的图标。锁定的图标将显示给未取得成就的用户,而解锁的图标将显示给已取得成就的用户。如果只提供了解锁的图标,将以解锁的图标的灰度版本显示锁定的图标。如果二者均未提供,将使用默认图标。
      • 使用每种图标类型下方的上传媒体上传成就图标。
    • 写入策略 - 在两个写入策略选项中选择一个:
      • 客户端权威是默认设置,意味着可以从客户端应用写或解锁成就进度。
      • 服务器权威意味着只能使用下面列出的 S2S API 写或更新成就。这通常用于在受信任的服务器运行游戏会话时减少作弊。仍可以从客户端应用查询成就信息和进度。
    • 是否对成就保密 - 该是/否开关用于选择是否隐藏成就标题、描述、图标和进度,直到完全取得或解锁成就。默认选择
    • 类型 - Meta Quest 平台支持三种类型的成就:简单、计数和位域。每种成就类型有不同的解锁机制。
      • 简单成就只有已解锁和未解锁两种状态。完成单一事件或目标时即可解锁。例如,当玩家到达山顶时,解锁简单成就。
      • 计数成就会在计数器到达定义的目标时进行解锁。因此需要定义触发计数成就要达到的目标。例如,目标为 10 的计数类型成就,在玩家击败 3 个(小于 10 的任意数字)僵尸时,将处于解锁过程中;在玩家击败 10 个僵尸时,成就将会解锁。
      • 位域成就会在达到位域中设置的目标位数时进行解锁。因此,需要定义触发位域成就的目标和位域长度。例如,当 bitfield_progress 是“000110”时,目标是 5 的位域成就处于解锁过程中;当 bitfield_progress 是“111110”时,将会解锁该位域成就。
  3. 保存成就后,选择发布。您随时可以在开发者面板中更新成就。
注意:您可以随时归档成就。归档不会删除成就或用户的进度,但会隐藏成就和用户的任何进度。您可以取消归档成就,以还原对用户的可见性。

集成成就

在开发者面板上创建成就后,如上所述,您就可以通过使用内置 Unreal 引擎成就 Blueprint 节点在 Unreal 中集成成就。注意事项:

对值进行相应转换

在 Unreal 引擎中,成就的数值范围设定为 0 到 100,因此您需要将数值转换至这一区间内。有关具体操作示例请参阅下表。
成就类型Unreal 数值转换示例
简单
已锁定:0,已解锁:100
计数
当前计数 * 100/目标值(最大值为 100)
此类成就的目标值为 10。当用户有 5 次计数时,在 Unreal 中对应值的计算方法为 5x100/10 = 50
位域
字符串中“1”的数量 *100/目标值(最大值为 100)
此类成就的 6 位中必须有 4 位进行了设置。用户的成就为 3 位 (000111) 时,在 Unreal 中对应值的计算方法为 3 * 100 / 4 = 75
下面描述的成就 Blueprint 节点使用 Unreal 引擎的 Online Subsystem(在线子系统)框架。如要在 Meta Quest 中使用这些节点,请在项目中启用 Online Subsystem Oculus 插件,并使用应用编号配置您的 DefaultEngine.ini。如需获取设置说明,请参阅平台 SDK:入门指南

检索并缓存数值

在应用启动时,您需要先将缓存的成就描述和缓存成就添加到您的 Blueprint 中。此步骤需要在调用检索或写入任何成就信息之前完成。要在应用中检索玩家的成就进度:
  1. 您可以在 Blueprint 中添加获取缓存的成就描述(在 Blueprint 的操作上下文菜单下的在线 > 成就中可以找到)以检索有关特定成就的信息,包括成就类型。
  2. 接着添加获取缓存的成就进度以获取该用户的进度。
  3. 将返回的值转换为正确的格式以便显示给用户。

写入成就进度

要在应用中为玩家写入成就进度:
  1. 在您的 Blueprint 中,首先添加获取缓存的成就描述以检索有关特定成就的信息,包括成就类型。
  2. 然后添加写入成就进度以记录该用户的进度。在写入进度时,请按以下方式转换进度:
    1. 简单:在调用时使用任何值即可解锁。
    2. 计数:将 WriteObject 中的值添加到成就进度中。仅支持 Int32、Int64、UInt32 和 UInt64 值。
    3. 位域:使用一系列 0 和 1 作为位掩码。Int32 值将被转换为其字符串表示形式,例如:101 → 101,字符串值将按原样使用。
Alternative: Meta XR Platform plugin
Meta XR 平台插件 (OVRPlatform) 在 OvrPlatform > Achievements(成就)类别下提供了专门的成就 Blueprint 节点,包括 Achievements_AddCountAchievements_UnlockAchievements_GetProgressByName。这些节点直接采用原生成就类型,不做 0–100 范围的比例转换。对于新项目,请考虑使用 Meta XR 平台插件,而不是上述 Online Subsystem 方法。

为服务器成就提出 REST 请求

如果将成就设置为服务器权威,您需要从受信任的服务器调用 API 到 Meta Quest 服务来增加和解锁成就。请参阅服务器到服务器基础知识页面来获取与 Meta Quest REST API 互动的相关信息。

创建或更新成就 (POST)

用于创建新成就或更新已存在的成就。这将为所有用户更新成就。
请求方法/URL:
POST https://graph.oculus.com/$APPID/achievement_definitions
参数:
参数必要/可选描述类型示例
access_token
必要
包含 OC|$APP_ID |$APP_SECRET 的 Bearer 口令
字符串
“OC|1234|456789”
api_name
必要
用于引用此 API 和客户端 SDK 中的成就的名称。这个字母数字字符串对应用来说必须是唯一的。如果成就存在,调用将会更新它。如果它不存在,调用将会使用此名称来创建成就。
字符串
“VISIT_3_CONTINENTS”
achievement_type
必要
这是成就类型。有三种类型的成就,请参阅上面的描述获取关于不同类型的信息。
有 SIMPLE、COUNT、BITFIELD 值的枚举
“SIMPLE”
achievement_write_policy
必要
确定谁可以写入成就进度。请参阅上面的描述获取关于两种不同写入策略的信息。
有 CLIENT_AUTHORITATIVE、SERVER_AUTHORITATIVE 值的枚举
“CLIENT_AUTHORITATIVE”
target
如果 成就achievement_type 是计数或位域,则为必要
要解锁的成就的事件发生次数。请参阅上面的描述获取关于目标的更多信息。
整数
50
bitfield_length
如果成就类型是位域,则为必要
该成就的位域大小。
整数
7
is_archived
可选。默认为 false。
指示是否归档成就的布尔值。也可用于对成就取消归档。归档不会删除成就或用户进度。
布尔值
“false”
title
必要
用户看到的成就的名称。
字符串
“到过 3 大洲”
description
必要
用户看到的文本描述。
字符串
“该成就的解锁条件是...”
unlocked_description _override
可选
解锁成就时用户看到的文本描述。
字符串
“恭喜!您已到过 3 大洲。”
is_secret
可选 - 默认是 false。
指示是否在取得成就前隐藏成就的布尔值。
布尔值
“false”
unlocked_image_file
可选 - 使用默认图像。
取得成就后显示的图标的本地路径。必须是 256x256 PNG 文件。
字符串
”@/path/to/unlocked_icon.png; type=image/png”
locked_image_file
可选 - 如果提供了解锁的图像,将使用灰度版本作为锁定的图像。否则,将使用默认图像。
取得成就前显示的图标的本地路径。必须是 256x256 PNG 文件。
字符串
”@/path/to/locked_icon.png; type=image/png”
创建/更新请求示例
curl -X POST -d "access_token=OC|$APP_ID|$APP_SECRET" -d "api_name=VISIT_3_CONTINENTS" -d "achievement_type=BITFIELD" -d "achievement_write_policy=SERVER_AUTHORITATIVE" -d "target=3" -d "bitfield_length=7" -d "is_archived=false" -d "title=Achievement Title" -d "description=How to earn me" -d "unlocked_description_override=You did it" -d "is_secret=false" -d "locked_image_file=@/path/to/locked_icon.png;type=image/png" -d "unlocked_image_file=@/path/to/unlocked_icon.png;type=image/png" https://graph.oculus.com/$APPID/achievement_definitions
响应示例
{"id":"1074233745960170"}

检索成就定义 (GET)

查询成就定义可让您获取要显示给用户的成就相关信息。
请求方法/URL:
GET https://graph.oculus.com/$APPID/achievement_definitions
参数:
参数必要/可选描述类型示例
access_token
必要
包含 OC|$APP_ID |$APP_SECRET 的 Bearer 口令
字符串
“OC|1234|456789”
api_names
可选
要获取的成就定义的名称。如果省略,将会返回所有成就定义。
字符串数组
[“VISIT_3_CONTINENTS”, “WALK_500_MILES”]
include_archived
可选
指示是否要包含已归档成就的布尔值。这只能在使用应用访问口令验证身份时使用。
布尔值
“false”
fields
可选
要检索的用逗号分隔的字段名称清单。可以包含:api_nameachievement_typeachievement_write_policytargetbitfield_lengthis_archivedtitledescriptionunlocked_description_overrideis_secretlocked_image_uriunlocked_image_uri。如果省略,将只返回编号。
字符串
“api_name,achievement_type”
字段定义与上面的创建或更新 API 调用相同。提供服务器图像 URI 而不是本地文件位置。
请求示例
curl -X GET "https://graph.oculus.com/$APP_ID/achievement_definitions?fields=api_name,achievement_type,achievement_write_policy,target,bitfield_length,is_archived,title,description,unlocked_description_override,is_secret,locked_image_uri,unlocked_image_uri&api_names=\[\"VISIT_3_CONTINENTS\"\]&access_token=OC\|$APP_ID\|$APP_SECRET"
响应示例
{
    "data": [{
        "id": "1074233745960170",
        "api_name": "VISIT_3_CONTINENTS",
        "achievement_type": "BITFIELD",
        "achievement_write_policy": "SERVER_AUTHORITATIVE",
        "target": 3,
        "bitfield_length": 7,
        "is_archived": false,
        "title": "Achievement Title",
        "description": "How to earn me",
        "unlocked_description_override": "You did it",
        "is_secret": false,
        "locked_image_uri": "https://scontent.oculuscdn.com/...",
        "unlocked_image_uri": "https://scontent.oculuscdn.com/..."
    }]
}

写入(并解锁)成就进度 (POST)

写入成就进度会更新用户在某个成就上的进度。对于计数类型的成就,这种方法会累积进度,而不是覆盖值。例如,add_count=25 会将计数增加 25,而不是将当前计数设置为 25。这样,在从多个来源同时更新成就或离线模式下从多个设备实施进度时,就可以轻松处理引起的冲突。
请求方法/URL:
POST https://graph.oculus.com/$USER_ID/achievements
参数:
参数必要/可选描述类型示例
access_token
必要
包含 OC|$APP_ID |$APP_SECRET 的 Bearer 口令
字符串
“OC|1234|456789”
api_name
必要
要更新的成就的名称。
字符串
“VISIT_3_CONTINENTS”
add_count
如果成就是计数类型,则为必要。
要为此成就填加到进度计数器的值。仅对计数成就有效。
整数
25
add_bits
如果成就是位域类型,则为必要。
要为此成就填加到进度的位。仅对位域成就有效。
字符串
“110001”
force_unlock
可选 - 默认是 false。
无论进度如何,立刻解锁成就。这必须用于解锁简单成就。
布尔值
“false”
请求示例
curl -X POST -d "access_token=OC|$APP_ID|$APP_SECRET" -d "api_name=MY_ACHIEVEMENT" -d "add_count=25" -d "force_unlock=true" https://graph.oculus.com/$USER_ID/achievements
响应示例
{"id":"1074233745960170","api_name":"MY_ACHIEVEMENT","just_unlocked":true}
响应将包含 just_unlocked 参数,指示此操作是否会导致解锁成就。

查询成就进度 (GET)

检索用户的成就进度。
请求方法/URI:
GET https://graph.oculus.com/$USER_ID/achievements
参数:
参数必要/可选描述类型示例
access_token
必要
包含 OC|$APP_ID |$APP_SECRET 的 Bearer 口令
字符串
“OC|1234|456789”
api_names
可选
要获取的成就定义的名称。如果省略,将会返回所有成就定义。
字符串数组
[“VISIT_3_CONTINENTS”, “WALK_500_MILES”]
fields
可选
如要检索的用逗号分隔的字段名称清单。可以包含:idunlock_timeis_unlockedcount_progress。如果省略,将只返回编号。
字符串
“api_name,achievement_type”
请求示例
curl -X GET "https://graph.oculus.com/$USERID/achievements?access_token=OC\|$APP_ID\|$APP_SECRET&api_names=\[\"VISIT_3_CONTINENTS\"\]&fields=target,bitfield_progress,is_unlocked,unlock_time"
响应示例
    {
    "data": [{
        "id": "1074233745960170",
        "bitfield_progress": "1001100",
        "is_unlocked": true,
        "unlock_time": 1459815726
    }]
 }

移除用户的所有成就和进度 (POST)

此方法将移除用户的所有锁定和解锁的成就进度。
请求方法/URI:
POST https://graph.oculus.com/achievement_remove_all
参数:
参数必要/可选描述类型示例
access_token
必要
包含 OC|$APP_ID |$APP_SECRET 的 Bearer 口令
字符串
“OC|1234|456789”
user_id
必要
要为其移除成就的用户编号。
字符串
“12345”
请求示例
curl -X POST "https://graph.oculus.com/achievement_remove_all?user_id=$USER_ID&access_token=OC\|$APP_ID\|$APP_SECRET"
响应示例
{"success":true}

疑难解答

如果发出 REST 请求获取服务器成就中提到的 API 对您无效,该怎么办?
请务必再次确认您的成就项的写入策略已设为服务器权威。如果是客户端权威,这些 REST 请求将无效。您需要使用 SDK 方法与您的成就互动。
如果写入策略是服务器权威,但 REST 请求仍然无效呢?
您需要检查是否将 $APPID$APP_SECRET 这样的 $VAR 替换成了可从 开发者中心 > 开发 > API 检索的实际值。