开发

Meta Quest 应用成就

更新时间: 2026年4月7日
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. 保存成就后,选择发布。您随时可以在开发者面板中更新成就。
注意:您可以随时归档成就。归档不会删除成就或用户的进度,但会隐藏成就和用户的任何进度。您可以取消归档成就,以还原对用户的可见性。

集成成就

创建成就后,您可以将它们集成到游戏中。当您调用这部分中的函数时,请务必使用您在开发者面板上指定的成就名称。
可以从您的客户端应用调用以下 SDK 方法。详情请参阅开放平台 SDK 参考内容
任务描述函数
检索关于特定成就的信息,包括成就名称、类型、目标或位域长度。
Platform.Achievements.GetDefinitionsByName()
检索关于用户在特定成就上的进度的信息,包括名称、解锁的状态、解锁成就的时间、当前位域和当前计数。
Platform.Achievements.GetProgressByName()
检索关于所有成就的信息,包括成就名称、类型、目标或位域长度。
Platform.Achievements.GetAllDefinitions()
检索关于用户在所有成就上的进度的信息,包括名称、解锁的状态、解锁成就的时间、当前位域和当前计数。
Platform.Achievements.GetAllProgress()
可以调用以下 SDK 方法来检索有客户端权威写策略的任何成就。如果成就是服务器权威,您需要使用下面部分中的 S2S REST 调用,从受信任的服务器进行更新。
任务描述函数
解锁指定的成就。这将完全解锁某个成就,包括计数和位域成就,而无论目标是否实现。
Platform.Achievements.Unlock()
增加计数成就上的计数。
Platform.Achievements.AddCount()
在位域类型成就中解锁一个或多个位。将位解锁后,它将一直处于解锁状态。例如,如果位域是 10011,您调用了传递 00110 的 AddFields,最终状态将为 10111。
Platform.Achievements.AddFields()

实施示例

下面的 Unity 示例展示了在您定义的事件上设置一个要解锁的成就。下面的示例取自 VRHoops 应用示例。在 Unity 的 Meta Quest 集成包中找到示例。如需了解更多信息,请参阅应用示例
该示例首先定义了在开发者面板上配置的名为 LIKES_TO_WIN 的成就。随后,它检查了更新消息,看看是否已解锁成就,如果是,则在应用中将成就设置为已解锁。否则,如果满足某个游戏条件(在该示例中,如果记录了胜利),游戏将会继续进行并增加成就计数。
using UnityEngine;
using System.Collections;
using Oculus.Platform;
using Oculus.Platform.Models;

public class AchievementsManager : MonoBehaviour
  {
    // API NAME defined on the dashboard for the achievement
    private const string LIKES_TO_WIN = "LIKES_TO_WIN";
    // true if the local user hit the achievement Count setup on the dashboard
    private bool m_likesToWinUnlocked;

    public bool LikesToWin
    {
        get { return m_likesToWinUnlocked; }
    }

    public void CheckForAchievmentUpdates()
    {
        Achievements.GetProgressByName(new string[]{LIKES_TO_WIN}).OnComplete(
            (Message<AchievementProgressList> msg) =>
            {
                foreach (var achievement in msg.Data)
                {
                    if (achievement.Name == LIKES_TO_WIN)
                    {
                        m_likesToWinUnlocked = achievement.IsUnlocked;
                    }
                }
            }
        );
    }
    public void RecordWinForLocalUser()
    {
        Achievements.AddCount(LIKES_TO_WIN, 1);
        CheckForAchievmentUpdates();
    }
}

为服务器成就提出 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 检索的实际值。