EOS Integration KitAlpha
v5.0.1

Achievements

Create, track, and unlock achievements to reward player accomplishments

Achievements reward players for completing tasks or reaching milestones. In EOS, achievements are tied to stats and can auto-unlock when stat thresholds are met.

Achievements require setup in the EOS Developer Portal. Create achievements and link them to stats before using the API.

Portal Setup

  1. Go to the EOS Developer Portal
  2. Navigate to Game ServicesAchievements
  3. Click + New Achievement
  4. Select the Stat Name and Stat Value threshold for auto-unlock
  5. Fill in achievement details (name, description, icons)

Achievements auto-unlock when the linked stat reaches the threshold. You can also manually unlock achievements using the API.

Query Achievement Definitions

Fetch all achievement metadata (names, descriptions, icons) from the server. Call this once at startup.

Query EIK Achievement Definitions node
Copy and paste into Unreal Engine Blueprint editor

Returns an array of achievement definitions with:

  • Achievement ID
  • Display names (locked/unlocked variants)
  • Descriptions (locked/unlocked variants)
  • Icon URLs
  • Hidden status
#include "EIKCore/Public/Interfaces/IEIKAchievements.h"

void UMyClass::QueryAchievementDefinitions()
{
    TSharedPtr<IEIKAchievements> Achievements = GetAchievementsInterface();
    if (!Achievements.IsValid()) return;

    Achievements->QueryAchievementDefinitions(0,
        FEIKAsyncCallback<FEIKQueryAchievementDefinitionsResult>::CreateLambda(
            [this](const TEIKAsyncResult<FEIKQueryAchievementDefinitionsResult>& Result)
            {
                if (Result.IsSuccessful())
                {
                    for (const FEIKAchievementDefinition& Def : Result.GetValue().Definitions)
                    {
                        UE_LOG(LogTemp, Log, TEXT("Achievement: %s - %s"),
                            *Def.AchievementId,
                            *Def.UnlockedDisplayName.ToString());
                    }
                }
            }));
}
#include "Online/OnlineServices.h"
#include "Online/Achievements.h"

using namespace UE::Online;

void UMyClass::QueryAchievementDefinitions()
{
    IOnlineServicesPtr Services = GetServices(EOnlineServices::Epic);
    IAchievementsPtr Achievements = Services->GetAchievementsInterface();

    FQueryAchievementDefinitions::Params Params;
    Params.LocalAccountId = GetLocalAccountId();

    Achievements->QueryAchievementDefinitions(MoveTemp(Params))
        .OnComplete([this](const TOnlineResult<FQueryAchievementDefinitions>& Result)
        {
            if (Result.IsOk())
            {
                UE_LOG(LogTemp, Log, TEXT("Achievement definitions loaded"));
            }
        });
}
#include "OnlineSubsystem.h"
#include "Interfaces/OnlineAchievementsInterface.h"

void UMyClass::QueryAchievementDefinitions()
{
    IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(FName(TEXT("EIK")));
    IOnlineAchievementsPtr Achievements = OnlineSub->GetAchievementsInterface();
    IOnlineIdentityPtr Identity = OnlineSub->GetIdentityInterface();

    FUniqueNetIdPtr UserId = Identity->GetUniquePlayerId(0);
    if (!UserId.IsValid()) return;

    Achievements->QueryAchievementDescriptions(*UserId,
        FOnQueryAchievementsCompleteDelegate::CreateLambda(
            [this](const FUniqueNetId& PlayerId, bool bWasSuccessful)
            {
                if (bWasSuccessful)
                {
                    UE_LOG(LogTemp, Log, TEXT("Achievement definitions loaded"));
                }
            }));
}

Query Achievement States

Fetch the player's achievement progress and unlock status.

Query EIK Achievement States node
Copy and paste into Unreal Engine Blueprint editor

Returns an array of achievement states with:

  • Achievement ID
  • Progress (0.0 to 1.0)
  • Unlock time (if unlocked)
void UMyClass::QueryAchievementStates()
{
    TSharedPtr<IEIKAchievements> Achievements = GetAchievementsInterface();

    Achievements->QueryAchievementStates(0,
        FEIKAsyncCallback<FEIKQueryAchievementStatesResult>::CreateLambda(
            [this](const TEIKAsyncResult<FEIKQueryAchievementStatesResult>& Result)
            {
                if (Result.IsSuccessful())
                {
                    for (const FEIKAchievementState& State : Result.GetValue().States)
                    {
                        UE_LOG(LogTemp, Log, TEXT("%s: %.0f%% %s"),
                            *State.AchievementId,
                            State.Progress * 100.f,
                            State.IsUnlocked() ? TEXT("(Unlocked)") : TEXT(""));
                    }
                }
            }));
}
void UMyClass::QueryAchievementStates()
{
    IAchievementsPtr Achievements = GetAchievementsInterface();

    FQueryAchievementStates::Params Params;
    Params.LocalAccountId = GetLocalAccountId();

    Achievements->QueryAchievementStates(MoveTemp(Params))
        .OnComplete([this](const TOnlineResult<FQueryAchievementStates>& Result)
        {
            if (Result.IsOk())
            {
                UE_LOG(LogTemp, Log, TEXT("Achievement states loaded"));
            }
        });
}
void UMyClass::QueryAchievementStates()
{
    IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(FName(TEXT("EIK")));
    IOnlineAchievementsPtr Achievements = OnlineSub->GetAchievementsInterface();
    FUniqueNetIdPtr UserId = OnlineSub->GetIdentityInterface()->GetUniquePlayerId(0);

    Achievements->QueryAchievements(*UserId,
        FOnQueryAchievementsCompleteDelegate::CreateLambda(
            [this, Achievements, UserId](const FUniqueNetId& PlayerId, bool bWasSuccessful)
            {
                if (bWasSuccessful)
                {
                    TArray<FOnlineAchievement> PlayerAchievements;
                    Achievements->GetCachedAchievements(*UserId, PlayerAchievements);

                    for (const FOnlineAchievement& Achievement : PlayerAchievements)
                    {
                        UE_LOG(LogTemp, Log, TEXT("%s: %.0f%%"),
                            *Achievement.Id, Achievement.Progress);
                    }
                }
            }));
}

Unlock Achievements

Manually unlock achievements. Useful for achievements not tied to stats.

Unlock EIK Achievements node
Copy and paste into Unreal Engine Blueprint editor

Pass an array of achievement IDs to unlock. The overlay will display for each unlocked achievement.

void UMyClass::UnlockAchievement(const FString& AchievementId)
{
    TSharedPtr<IEIKAchievements> Achievements = GetAchievementsInterface();

    FEIKUnlockAchievementsParams Params;
    Params.AchievementIds.Add(AchievementId);

    Achievements->UnlockAchievements(0, Params,
        FEIKAsyncCallbackVoid::CreateLambda(
            [AchievementId](const TEIKAsyncResult<void>& Result)
            {
                if (Result.IsSuccessful())
                {
                    UE_LOG(LogTemp, Log, TEXT("Achievement unlocked: %s"), *AchievementId);
                }
            }));
}
void UMyClass::UnlockAchievement(const FString& AchievementId)
{
    IAchievementsPtr Achievements = GetAchievementsInterface();

    FUnlockAchievements::Params Params;
    Params.LocalAccountId = GetLocalAccountId();
    Params.AchievementIds.Add(AchievementId);

    Achievements->UnlockAchievements(MoveTemp(Params))
        .OnComplete([](const TOnlineResult<FUnlockAchievements>& Result) {});
}
void UMyClass::UnlockAchievement(const FString& AchievementId)
{
    IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(FName(TEXT("EIK")));
    IOnlineAchievementsPtr Achievements = OnlineSub->GetAchievementsInterface();
    FUniqueNetIdPtr UserId = OnlineSub->GetIdentityInterface()->GetUniquePlayerId(0);

    FOnlineAchievementsWriteRef WriteObject = MakeShared<FOnlineAchievementsWrite>();
    WriteObject->SetFloatStat(FName(*AchievementId), 100.0);

    Achievements->WriteAchievements(*UserId, WriteObject,
        FOnAchievementsWrittenDelegate::CreateLambda(
            [](const FUniqueNetId& PlayerId, bool bWasSuccessful)
            {
                if (bWasSuccessful)
                {
                    UE_LOG(LogTemp, Log, TEXT("Achievement unlocked"));
                }
            }));
}

Achievement Events

Listen for achievement unlock notifications.

Bind to events from EIK Achievements Subsystem or use the async node callbacks.

EventWhen Fired
On Achievement UnlockedAchievement was unlocked (overlay appears)
On Achievement State UpdatedAchievement progress changed
void UMyClass::SetupAchievementEvents()
{
    TSharedPtr<IEIKAchievements> Achievements = GetAchievementsInterface();
    if (!Achievements.IsValid()) return;

    Achievements->OnAchievementUnlocked().AddUObject(this, &UMyClass::HandleAchievementUnlocked);
    Achievements->OnAchievementStateUpdated().AddUObject(this, &UMyClass::HandleAchievementUpdated);
}

void UMyClass::HandleAchievementUnlocked(const FEIKAccountId& AccountId, const FString& AchievementId)
{
    UE_LOG(LogTemp, Log, TEXT("Achievement unlocked: %s"), *AchievementId);
}

void UMyClass::HandleAchievementUpdated(const FEIKAccountId& AccountId, const FString& AchievementId)
{
    // Re-query to get updated progress
}

Helper Functions

The Achievements Library provides cached access after querying:

FunctionReturnsDescription
GetAchievementIds()TArray<FString>All achievement IDs
GetAchievementDefinition(Id)FEIKAchievementDefinitionGet definition by ID
GetAchievementState(Id)FEIKAchievementStateGet player progress
IsAchievementUnlocked(Id)boolCheck if unlocked
GetAchievementProgress(Id)floatGet progress (0.0-1.0)
GetAchievementUnlockTime(Id)FDateTimeWhen unlocked
GetAchievementDisplayName(Def, bUnlocked)FTextGet appropriate name
GetAchievementDescription(Def, bUnlocked)FTextGet appropriate description
GetAchievementIconUrl(Def, bUnlocked)FStringGet appropriate icon URL
GetUnlockedAchievementCount(States)int32Count unlocked in array

Common Patterns

Display Achievement List

void UMyClass::DisplayAchievements()
{
    TSharedPtr<IEIKAchievements> Achievements = GetAchievementsInterface();

    TArray<FString> Ids = Achievements->GetAchievementIds(0);
    for (const FString& Id : Ids)
    {
        bool bDefFound, bStateFound;
        FEIKAchievementDefinition Def = Achievements->GetAchievementDefinition(0, Id, bDefFound);
        FEIKAchievementState State = Achievements->GetAchievementState(0, Id, bStateFound);

        if (bDefFound && bStateFound)
        {
            bool bUnlocked = State.IsUnlocked();
            FText Name = bUnlocked ? Def.UnlockedDisplayName : Def.LockedDisplayName;
            FText Desc = bUnlocked ? Def.UnlockedDescription : Def.LockedDescription;
            FString Icon = bUnlocked ? Def.UnlockedIconUrl : Def.LockedIconUrl;

            // Add to UI list
            AddAchievementToUI(Name, Desc, Icon, State.Progress, bUnlocked);
        }
    }
}

Track Progress

Achievements linked to stats update automatically. For manual tracking:

void UMyClass::OnEnemyKilled()
{
    EnemiesKilled++;

    // Update stat (achievement auto-unlocks at threshold)
    Stats->IngestStat(0, FName("EnemiesKilled"), EnemiesKilled);

    // Or manually unlock at milestone
    if (EnemiesKilled == 100)
    {
        UnlockAchievement(TEXT("KILL_100_ENEMIES"));
    }
}

On this page