The Unity client is available from Heroic Labs. Contact us to request access.
The Hiro.unitypackage contains all source code and DLL dependencies required in the client code.
After downloading the file:
Drag or import it into your Unity project
Set the editor Api Compatibility Level setting to .NET Standard 2.1 (from the Edit -> Project Settings -> Player -> Other Settings -> Configuration menu).
API Compatibility Level
While Hiro is developed against .NET Standard 2.1, the .NET Framework option will work if you need or would like to use it instead.
A key philosophy of Hiro is its opinionated and structured method for bootstrapping your game using a deterministic startup. This is achieved by inheriting from the HiroCoordinator and sequentially configuring and adding the required game Systems.
Hiro provides several different Systems out-of-the-box, such as the NakamaSystem (which handles the connection to Nakama and keeps a reference to the Client, Session and Socket objects) and the EconomySystem (which handles all aspects of in-game economy including both soft and hard currency purchases).
In the Scene Hierarchy, create a new Game Object and call it GameCoordinator.
Attach a new C# script to the object and call it GameCoordinator.
Inherit from HiroCoordinator and create a function to handle player authentication, telling Hiro how you want to authorize users against Nakama. This example creates an authorizer that uses Device Authentication:
publicclassGameCoordinator:HiroCoordinator{privateconststringPlayerPrefsAuthToken="nakama.AuthToken";privateconststringPlayerPrefsRefreshToken="nakama.RefreshToken";privateconststringPlayerPrefsDeviceId="nakama.DeviceId";privatestaticNakamaSystem.AuthorizerFuncNakamaAuthorizerFunc(INetworkMonitormonitor){returnasyncclient=>{varauthToken=PlayerPrefs.GetString(PlayerPrefsAuthToken);varrefreshToken=PlayerPrefs.GetString(PlayerPrefsRefreshToken);varsession=Session.Restore(authToken,refreshToken);// Add an hour, so we check whether the token is within an hour of expiration to refresh it.varexpiredDate=DateTime.UtcNow.AddHours(1);if(session!=null&&(!monitor.Online||!session.HasRefreshExpired(expiredDate))){returnsession;}vardeviceId=PlayerPrefs.GetString(PlayerPrefsDeviceId,SystemInfo.deviceUniqueIdentifier);session=awaitclient.AuthenticateDeviceAsync(deviceId);PlayerPrefs.SetString(PlayerPrefsAuthToken,session.AuthToken);PlayerPrefs.SetString(PlayerPrefsRefreshToken,session.RefreshToken);PlayerPrefs.SetString(PlayerPrefsDeviceId,deviceId);if(session.Created){Debug.LogFormat("New user account '{0}' created.",session.UserId);}returnsession;};}}
Override the CreateSystemsAsync method of the HiroCoordinator to configure our initial setup. The first System you need to initialize is the NakamaSystem. This System is responsible for handling connections and authorization with the Nakama server and maintaining the Client, Session and Socket objects:
publicclassGameCoordinator:HiroCoordinator{protectedoverrideTask<Systems>CreateSystemsAsync(){// Nakama server address.conststringscheme="http";conststringhost="127.0.0.1";constintport=7350;conststringserverKey="defaultkey";varlogger=newHiro.Unity.Logger();// Set up network connectivity probes.varnakamaProbe=newNakamaClientNetworkProbe(TimeSpan.FromSeconds(60));varmonitor=newNetworkMonitor(InternetReachabilityNetworkProbe.Default,nakamaProbe);monitor.ConnectivityChanged+=(_,args)=>{Instance.Logger.InfoFormat($"Network is online: {args.Online}");};varnakamaSystem=newNakamaSystem(logger,scheme,host,port,serverKey,NakamaAuthorizerFunc(monitor),nakamaProbe);nakamaSystem.Client.ReceivedSessionUpdated+=session=>{PlayerPrefs.SetString(PlayerPrefsAuthToken,session.AuthToken);PlayerPrefs.SetString(PlayerPrefsRefreshToken,session.RefreshToken);};// Create our systems containervarsystems=newSystems("HiroSystemsContainer",monitor,logger);systems.Add(nakamaSystem);// Further system initialization here...returnTask.FromResult(systems);}}
To ensure the system has the latest data from Nakama, call the RefreshAsync function. This same refresh logic applies to any system that caches state locally.
1
awaitnakamaSystem.RefreshAsync();
The NakamaSystem provides some additional quality of life properties and functions, such as providing direct access to the IApiAccount via the Account property or retrieving a storage object via the ReadStorageObjectAsync function.