> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 更新作品管理的成就

> 示例 XSAPI 代码，展示如何使用 XblAchievementsUpdateAchievementAsync 解锁作品管理的 XBOX Live 成就或报告完成进度。

<a id="top" />

本主题包括以下内容：

* [解锁成就](#unlocking-an-achievement)
* [更新成就的完成进度](#updating-an-achievement)

<a id="unlocking-an-achievement" />

## 解锁成就

在通过合作伙伴中心配置成就并发布到您的开发沙盒后，您的作品可以通过调用 [XblAchievementsUpdateAchievementAsync](/reference/live/xsapi-c/achievements_c/functions/xblachievementsupdateachievementasync) API 来解锁它们。
有关更多信息，请参阅下一节中的示例代码。

要解锁成就，请将 `percentComplete` 设置为 100。
如果用户处于联机状态，则请求会立即发送到 XBOX 服务成就服务，并触发以下用户体验。

* 用户收到成就已解锁通知。
* 指定的成就在用户的作品成就列表中显示为已解锁。
* 已解锁的成就将添加到用户的活动源中。

<Note>无论使用基于事件的成就还是作品管理的成就，成就的用户体验在视觉上是相同的。</Note>

如果用户处于脱机状态，则解锁请求会在用户设备上本地排队。
当它重新建立网络连接时，请求会自动发送到成就服务（游戏无需采取任何操作来触发此操作），并且发生前面所述的用户体验。

<a id="updating-an-achievement" />

## 更新成就的完成进度

要更新用户在解锁成就方面的进度，请调用 [XblAchievementsUpdateAchievementAsync](/reference/live/xsapi-c/achievements_c/functions/xblachievementsupdateachievementasync)。将 `percentComplete` 参数设置为 1-100 之间的整数。
有关更多信息，请参阅以下示例代码。

成就的进度只能增加。
如果 `percentComplete` 设置为小于成就的上次 `percentComplete` 值的数字，则更新将被忽略。
例如，如果成就的 `percentComplete` 之前已设置为 75，则发送值为 25 的更新将被忽略。成就仍然显示为完成 75%。

如果 `percentComplete` 设置为 100，则成就将被解锁。

如果 `percentComplete` 设置为大于 100 的数字，则 API 的行为就像您将数字精确设置为 100 一样。

### 更新当前作品的成就

您可以通过按如下所示调用 [XblAchievementsUpdateAchievementAsync](/reference/live/xsapi-c/achievements_c/functions/xblachievementsupdateachievementasync) 来更新当前作品的成就。

**Flat C API**

```cpp theme={null}
auto asyncBlock = std::make_unique<XAsyncBlock>();
asyncBlock->queue = queue;
asyncBlock->context = nullptr;
asyncBlock->callback = [](XAsyncBlock* asyncBlock)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock }; // Take over ownership of the XAsyncBlock*.
    auto result = XAsyncGetStatus(asyncBlock, false);
    if (SUCCEEDED(result))
    {
        // The achievement was updated.
    }
    else if (result == HTTP_E_STATUS_NOT_MODIFIED)
    {
        // The achievement wasn't updated.
    }
    else
    {
        // The achievement failed to update.
    }
};

HRESULT hr = XblAchievementsUpdateAchievementAsync(
    xboxLiveContext,
    xboxUserId,
    achievementId.c_str(),
    percentComplete,
    asyncBlock.get()
);
if (SUCCEEDED(hr))
{
    // The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* because the callback will take over ownership.
    // If the call fails, std::unique_ptr will keep ownership and delete XAsyncBlock*.
    asyncBlock.release();
}
```

有关更多信息，请参阅以下内容：

* [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)
* [XAsyncGetStatus](/reference/system/xasync/functions/xasyncgetstatus)
* [XblAchievementsUpdateAchievementAsync](/reference/live/xsapi-c/achievements_c/functions/xblachievementsupdateachievementasync)

### 更新其他作品的成就

您可以使用 [XblAchievementsUpdateAchievementForTitleIdAsync](/reference/live/xsapi-c/achievements_c/functions/xblachievementsupdateachievementfortitleidasync) 更新其他 `titleId` 的成就，如下所示。

**Flat C API**

```cpp theme={null}
auto asyncBlock = std::make_unique<XAsyncBlock>();
asyncBlock->queue = queue;
asyncBlock->context = nullptr;
asyncBlock->callback = [](XAsyncBlock* asyncBlock)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock }; // Take over ownership of the XAsyncBlock*.
    auto result = XAsyncGetStatus(asyncBlock, false);
    if (SUCCEEDED(result))
    {
        // The achievement was updated.
    }
    else if (result == HTTP_E_STATUS_NOT_MODIFIED)
    {
        // The achievement wasn't updated.
    }
    else
    {
        // The achievement failed to update.
    }
};

HRESULT hr = XblAchievementsUpdateAchievementForTitleIdAsync(
    xboxLiveContext,
    xboxUserId,
    titleId,
    scid,
    achievementId.c_str(),
    percentComplete,
    asyncBlock.get()
);
if (SUCCEEDED(hr))
{
    // The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* because the callback will take over ownership.
    // If the call fails, std::unique_ptr will keep ownership and delete XAsyncBlock*.
    asyncBlock.release();
}
```

有关更多信息，请参阅以下内容：

* [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)
* [XAsyncGetStatus](/reference/system/xasync/functions/xasyncgetstatus)
* [XblAchievementsUpdateAchievementForTitleIdAsync](/reference/live/xsapi-c/achievements_c/functions/xblachievementsupdateachievementfortitleidasync)

[返回到本主题顶部。](#top)


## Related topics

- [作品管理的成就示例代码](/zh-CN/services/xbox-services/player-data/achievements/title-managed/how-to/live-achievements-howto-nav.md)
- [将 GDK 集成到 4.26 之前的 Unreal Engine 项目](/zh-CN/build/gdk-and-engines/unreal/unreal-legacy.md)
- [获取作品管理的成就](/zh-CN/services/xbox-services/player-data/achievements/title-managed/how-to/live-how-to-get-achievements.md)
- [作品管理的成就概念](/zh-CN/services/xbox-services/player-data/achievements/title-managed/concepts/live-achievements-tm-concepts-nav.md)
- [作品管理的成就门户配置](/zh-CN/services/xbox-services/player-data/achievements/title-managed/config/live-achievements-tm-config-nav.md)
