Hiro Teams Sample Project

The official sample project for the Hiro Teams system. This project demonstrates how to create and manage teams (also known as clans/guilds), handle member roles and permissions, track team stats and wallets, and interact with the team mailbox. It’s built with minimal boilerplate so you can easily copy the code into your own game.

Features

  • Browse all available teams, search by name, language, open/closed status, and activity level.
  • Create teams with custom names, descriptions, language tags, and open/closed access.
  • Manage team members with a full role hierarchy: Super Admin, Admin, Member, and join requests with promote, demote, kick, and ban actions.
  • View team stats and wallet balances, claim mailbox rewards, and view team stats from an admin panel.

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 UnityHiroTeams 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 -> UnityHiroTeams -> 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/
├── UnityHiroTeams/
    ├── 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 (HiroTeamsCoordinator.cs) #

Extends HiroCoordinator to configure Nakama, register the TeamsSystem and EconomySystem, 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
20
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(HiroTeamsCoordinator), monitor, storage, logger);
    systems.Add(nakamaSystem);
    var teamsSystem = new TeamsSystem(logger, nakamaSystem);
    systems.Add(teamsSystem);
    var economySystem = new EconomySystem(logger, nakamaSystem, EconomyStoreType.Unspecified);
    systems.Add(economySystem);

    return Task.FromResult(systems);
}

API reference: Hiro Initialization


Controller (HiroTeamsController.cs) #

Bridges the UI and the Hiro Teams API. Handles authentication events, maintains the team list and member cache, and exposes async methods for every team operation.

Team discovery #

Refresh teams

Refresh the TeamsSystem, then populate the local team list.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public async Task<int?> RefreshTeams(int tabIndex)
{
    Teams.Clear();

    await _teamsSystem.RefreshAsync();

    SelectedTeam = null;
    _selectedTeamId = string.Empty;
    return null;
}

Search teams

Filter teams server-side by name, language tag, and minimum activity.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
public async Task SearchTeams(
    string teamName, string language,
    int minActivity, bool? openFilter = null)
{
    Teams.Clear();

    var results = await _teamsSystem.SearchTeamsAsync(
        name: teamName ?? "",
        langTag: language ?? "",
        limit: teamEntriesLimit,
        minActivity: minActivity
    );

    SelectedTeam = null;
    _selectedTeamId = string.Empty;
    SelectedTeamMembers.Clear();
}

Team lifecycle #

Create a team

Serialize avatar data as JSON and pass it alongside the team name, description, open/closed flag, and language tag.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
public async Task CreateTeam(
    string teamName, string description,
    bool isOpen, int backgroundIndex,
    int iconIndex, string language = "en")
{
    var avatarDataJson = JsonUtility.ToJson(new AvatarData
    {
        backgroundIndex = backgroundIndex,
        iconIndex = iconIndex
    });

    await _teamsSystem.CreateTeamAsync(
        teamName,
        description,
        isOpen,
        avatarDataJson,
        language,
        "{}"
    );
}

Join, leave, and delete

Single-call wrappers around the TeamsSystem for joining an open team, leaving the current team, and deleting a team (Super Admin only).

Member management #

Role-based actions

Promote, demote, kick, and ban members through the TeamsSystem. Handle join requests by approving or rejecting them. See Roles and permissions for more nformation on team roles and permissable actions.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public async Task PromoteUser(string userId)
{
    if (SelectedTeam == null) return;
    await _teamsSystem.PromoteUsersAsync(SelectedTeam.Id, new[] { userId });
}

public async Task AcceptJoinRequest(string userId)
{
    if (SelectedTeam == null) return;
    await _teamsSystem.ApproveJoinRequestAsync(SelectedTeam.Id, userId);
}

Mailbox #

List and claim rewards

Fetch claimable mailbox entries from the TeamsSystem and claim them individually or all at once.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public async Task<List<IRewardMailboxEntry>>
    GetMailboxEntriesAsync()
{
    MailboxEntries.Clear();

    if (_teamsSystem?.Team == null) return MailboxEntries;

    var mailbox = await _teamsSystem.ListMailboxAsync();
    foreach (var entry in mailbox.Entries)
    {
        if (entry.CanClaim)
        {
            MailboxEntries.Add(entry);
        }
    }

    return MailboxEntries;
}

API reference: Teams


Views #

TeamsView

Main screen handling two top-level tabs (All Teams / My Team), the team list, selected team detail panel, team-level tabs (Members, Gifts, Chat, Mailbox, About), search and create modals, a debug modal for adjusting team stats, and error handling. Non-members see a preview panel with public stats; members see the full tabbed interface with role-appropriate action buttons.

TeamView

Single team list entry showing the avatar, team name, and member count.

TeamMemberView

Per-member row in the members list. Displays username and role, then conditionally shows accept/decline, promote/demote, kick, and ban buttons based on the viewer’s role relative to the listed member.

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