Hiro Achievements Sample Project

The official sample project for the Hiro Achievements system. This project shows how to track goals, gate content with prerequisites, and deliver rewards using the Hiro SDK in Unity. It’s built with minimal boilerplate so you can easily copy the code into your own game.

Features

  • Track quests, dailies, and repeatable achievements with optional sub-achievements.
  • Show locked achievements with prerequisite hints, and unlock them as requirements are completed.
  • Update progress, view objectives, and claim rewards that sync to the Hiro wallet.
  • Filter achievements by category.

Installation

The installation steps and resulting folder structure will vary depending on if you downloaded the project from Github or the Unity Asset Store.

Note: This project was built with Unity 6.0+ in mind. Whilst the majority of the template is not version specific, the UI may not behave as intended on older versions of Unity.

For optimal display, set your game resolution in the Unity Editor to 1920x1080

  1. Clone or download the Sample Projects repository onto your machine.
  2. From the Unity Hub, click Add -> Add project from disk and choose the top-level UnityHiroAchievements folder.
  3. You may see several warnings about Editor version incompatibility. Feel free to ignore these messages as long as you're on Unity 6 or greater. Continue on until you arrive at the main Editor UI.
  4. Open the main scene by navigating to Assets -> UnityHiroAchievements -> Scenes -> Main.
  5. Hit Play.

The project connects to our demo server so you can see the features in action immediately.
Note: The server is reset on the 1st of every month at 00:00 UTC.

Folder structure

Assets/
├── UnityHiroAchievements/
    ├── HeroicUI/           # UI assets and styling
    ├── Scripts/            # Main project code
    ├── UI/                 # UI Builder files
    └── ...                 # Everything else
├── Packages/               # Contains the Nakama Unity package

Code overview #

The project uses Hiro’s systems-based architecture, which provides an opinionated structure for building games with pre-configured systems.

Coordinator (HiroAchievementsCoordinator.cs) #

Extends HiroCoordinator to configure Nakama, register Hiro systems, and expose a reusable authorizer for device-based login.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// Create and register Hiro systems
protected override Task<Systems> CreateSystemsAsync()
{
    var logger = new Hiro.Unity.Logger();
    var monitor = NetworkMonitor.Default;
    var client = localHost
        ? new Client("http", "127.0.0.1", 7350, "defaultkey")
        : new Client(scheme, host, port, serverKey);

    var nakamaSystem = new NakamaSystem(logger, client, NakamaAuthorizerFunc());
    var storage = MemoryStorage.Default;

    var systems = new Systems(nameof(HiroAchievementsCoordinator), monitor, storage, logger);
    systems.Add(nakamaSystem);
    systems.Add(new InventorySystem(logger, nakamaSystem));
    systems.Add(new EconomySystem(logger, nakamaSystem, EconomyStoreType.Unspecified));
    systems.Add(new AchievementsSystem(logger, nakamaSystem));
    return Task.FromResult(systems);
}

API reference: Hiro Initialization

Controller (AchievementsController.cs) #

Bridges the UI and Hiro Achievements API. Handles authentication events, category filtering, and orchestrates updates across achievements, sub-achievements, and rewards.

Load achievements

Refresh the Hiro achievements system, clear existing caches, and repopulate the controller’s local lists with all achievements and repeatable achievements, including locked items.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
public async Task LoadAchievements()
{
    AllAchievements.Clear();
    RepeatAchievements.Clear();

    await _achievementsSystem.RefreshAsync();

    // Get all achievements (including locked ones)
    var achievements = _achievementsSystem.GetAchievements();
    AllAchievements.AddRange(achievements);

    // Get repeatable achievements (including locked ones)
    var repeatAchievements = _achievementsSystem.GetRepeatAchievements();
    RepeatAchievements.AddRange(repeatAchievements);

    Debug.Log($"Loaded {AllAchievements.Count} achievements, {RepeatAchievements.Count} repeatable");
}

Update achievements progress

Validate the achievement ID and progress. Send a progress update to Hiro Achievements, then refresh local achievement and economy data so lists reflect the latest state.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
public async Task UpdateAchievementProgress(string achievementId, long progress)
{
    if (string.IsNullOrEmpty(achievementId))
        throw new Exception("Invalid achievement ID.");

    if (progress <= 0)
        throw new Exception("Progress must be greater than 0.");

    var updates = new Dictionary<string, long>
    {
        { achievementId, progress }
    };

    await _achievementsSystem.UpdateAchievementsAsync(updates);
    await RefreshAchievements();
}

Claim rewards and refresh the wallet

Claim the reward for the selected achievement or sub‑achievement. If a sub‑achievement is selected, claim its reward and return. Otherwise, verify a main achievement is selected and claim its reward. Use the claimTotal flag to claim the total reward.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// Claim rewards for the selected achievement (or sub-achievement) and sync the wallet UI
public async Task ClaimAchievementReward(bool claimTotal = true)
{
    if (_selectedSubAchievement != null)
    {
        await ClaimAchievementReward(_selectedSubAchievement.Id, claimTotal);
        return;
    }

    if (_selectedAchievement == null)
        throw new Exception("No achievement selected.");

    await ClaimAchievementReward(_selectedAchievement.Id, claimTotal);
}

Achievements view (AchievementsView.cs) #

Connect the UI Toolkit document to the controller logic. Handle tab filters for dailies, quests, and achievements; populate the achievements list; show prerequisites and rewards; and wire action buttons for progress and claim. Observe the Hiro wallet so currency changes appear immediately after a claim.

Sub-achievement view (SubAchievementItemView.cs) #

Format sub‑achievement objectives in the details panel. Show per‑objective progress, reward text, and status badges; send selection events to the controller for targeted updates.

Prerequisite helpers (PrerequisiteDisplayHelper.cs, AchievementProgressHelper.cs) #

Use utility classes to centralize progress calculations, lock‑state checks, and formatted prerequisite messages, keeping list items and detail views consistent.

Account Switcher

The Account Switcher lets you explore the project as different players without managing multiple builds. Use it to test features from different accounts.

How to use:

  1. Open the Account Switcher panel (Tools > Nakama > Account Switcher).
  2. Select different accounts from the dropdown to switch between up to four test users.
  3. Each account is automatically created the first time you select it.

Key points:

  • Only works while your game is running in Play mode.
  • Usernames will display in the panel after switching to an account for the first time.

Setting up your own Nakama server with Hiro

While this project works with our demo server, you'll want to set up your own Nakama and Hiro instance to customize the features and configurations.

Prerequisites

Before you can set up Hiro, you'll need to:

  1. Install Nakama: Follow the Nakama installation guide to get Nakama running with Docker.
  2. Obtain Hiro: Hiro is available to licensed users. Contact us to obtain your license.
  3. Install Hiro: Once you have your license key, follow the Hiro installation guide.

Configure Hiro

This sample project ships with specific Hiro system configurations on the server. You can view the exact configuration files used in our demo server here: Demo server configurations.

Copy the JSON files to your server (such as inside a definitions directory) and update main.go to initialize the required Hiro systems according to the installation guide or view the example on Github.

Connect this Unity project to your server

After installing Nakama and Hiro and running it locally with the appropriate configurations, edit these settings in the Unity Editor to connect to your server:

  1. Select the main coordinator component from the scene hierarchy panel.
  2. Open the Inspector tab.
  3. Look for the field inputs under Nakama Settings and replace them with the following:
    1. Scheme: http
    2. Host: 127.0.0.1
    3. Port: 7350
    4. Server Key: defaultkey

Additional resources