> ## 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.

# 타이틀 관리형 업적 업데이트

> XblAchievementsUpdateAchievementAsync를 사용하여 타이틀 관리형 XBOX Live 업적을 잠금 해제하거나 완료 진행률을 보고하는 방법을 보여주는 예제 XSAPI 코드입니다.

<a id="top" />

이 항목에서는 다음을 다룹니다.

* [업적 잠금 해제](#unlocking-an-achievement)
* [업적의 완료 진행률 업데이트](#updating-an-achievement)

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

## 업적 잠금 해제

업적이 Partner Center를 통해 구성되고 개발 샌드박스에 게시된 후 타이틀은 [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

- [타이틀 관리형 업적 예제 코드](/ko/services/xbox-services/player-data/achievements/title-managed/how-to/live-achievements-howto-nav.md)
- [방법 안내](/ko/services/xbox-services/player-data/achievements/title-managed/how-to/index.md)
- [Partner Center에서 타이틀 관리형 업적 구성](/ko/services/xbox-services/player-data/achievements/title-managed/config/live-achievements-tm-config.md)
- [타이틀 관리형 업적](/ko/services/xbox-services/player-data/achievements/title-managed/live-achievements-tm-nav.md)
- [타이틀 관리형 업적 개념](/ko/services/xbox-services/player-data/achievements/title-managed/concepts/live-achievements-tm-concepts-nav.md)
