Unity SDK
The Unity SDK is the UPM package build.rudder.sdk. It ships
Rudder.Sdk.dll (the C# SDK) with Unity adapters: a
UnityWebRequest transport, PlayerPrefs storage for tokens and the device
id, and the Rudder component, which pumps state sync and raises state events
on the main thread.
Requires Unity 6000.0 or newer. Current version: 0.1.0. Versions stay
0.x until the API is stable, and any minor release may break it.
Installation
Section titled “Installation”Add the Rudder scoped registry and both dependencies to
Packages/manifest.json:
{ "scopedRegistries": [ { "name": "Rudder", "url": "https://hub.rudder.build/api/packages/rudder/npm/", "scopes": ["build.rudder"] } ], "dependencies": { "build.rudder.sdk": "0.1.0", "com.unity.nuget.newtonsoft-json": "3.2.2" }}com.unity.nuget.newtonsoft-json is required: Rudder.Sdk serializes with
Newtonsoft.Json and the package does not bundle it.
Namespaces:
RudderSdk.Unity:Rudder,RudderConfiguration,RudderState;RudderSdk:RudderClient,SyncedState<T>, exceptions;RudderSdk.Models.*:PlayerProfile,Wallet,CatalogCurrency,StorageItem, …;RudderSdk.Modules: your generated module client.
Configuration
Section titled “Configuration”- Create a configuration asset: Assets > Create > Rudder > Configuration.
- Set Project Key to the SDK key from Project Settings in the
dashboard. The key selects
stagingorprod. - Add the
Ruddercomponent to a GameObject in your startup scene and assign the asset.
| Field | Default | Notes |
|---|---|---|
ProjectKey | — | Required. |
BaseUrl | https://api.rudder.build | API base URL. |
TimeoutSeconds | 10 | HTTP request timeout. |
Keep the key out of version control: use a gitignored asset and commit an
.example copy.
Bootstrap
Section titled “Bootstrap”using RudderSdk.Unity;using UnityEngine;
public class Bootstrap : MonoBehaviour{ async void Start() { var client = Rudder.Initialize(); client.Player.Changed += profile => Debug.Log("wallets: " + profile.Wallets?.Count); await client.Auth.LoginWithDeviceAsync("global", "en", nickname: "Player"); await client.Player.LoadAsync(); }}Rudderis aMonoBehaviourthat must already be in the scene; the SDK never creates its own GameObject. It survives scene loads, and a duplicate destroys itself.Rudder.Initialize()is synchronous and idempotent. It reads the configuration and returns theRudderClient, and throws when the component or the asset is missing.Rudder.StateisNotInitialized,Initializing,ReadyorFailed;Rudder.LastErrorholds the initialization error.Rudder.Clientreturns the client and throws untilInitialize()has run.Rudder.Ready(aTask<RudderClient>) and the staticRudder.Initializedevent serve add-ons that load later.
The client exposes Auth, Player, Catalog, Storage, Modules and
Sync, the same surface as the C# SDK.
Authentication
Section titled “Authentication”await client.Auth.LoginWithDeviceAsync("global", "en", nickname: "Player");
await client.Auth.LoginWithGoogleAsync(idToken, "global", "en");await client.Auth.LoginWithAppleAsync(idToken, "global", "en");await client.Auth.LoginWithCustomAsync(customData, "global", "en", provider: "steam");
await client.Auth.LinkWithGoogleAsync(idToken);await client.Auth.LinkWithAppleAsync(idToken);await client.Auth.LinkWithCustomAsync(customData, provider: "steam");await client.Auth.UnlinkIdentityAsync("google");- The device id is a GUID generated once and stored in
PlayerPrefs(rudder_device_id). Do not passSystemInfo.deviceUniqueIdentifier. - Access and refresh tokens persist in
PlayerPrefs. - A 401 triggers one automatic refresh and one retry.
Auth.AuthStateChangedfiresSignedInafter a login andSignedOutafter a logout or a failed refresh.Auth.Logout()drops the session.- Every login and token refresh sends
platform(fromApplication.platform) andappVersion(defaultApplication.version).
See Authentication for providers and errors.
State and sync
Section titled “State and sync”Player, Catalog and Storage cache their values. LoadAsync fetches
once, ReloadAsync always fetches, and Changed fires on the main thread
(the next frame) after every fetch.
The Rudder component calls client.Sync.TickAsync every frame: every 30
seconds (±20%) the SDK polls /sdk/v1/sync and reloads the loaded states
whose revision grew. Polling pauses while the application is paused. Do not
add your own sync timer.
var profile = await client.Player.LoadAsync();var gold = profile.Wallets?.FirstOrDefault(w => w.Currency == "gold")?.Balance ?? 0;long wins = 0;profile.Counters?.TryGetValue("wins", out wins);
var currencies = await client.Catalog.LoadAsync();Counters holds the values of number counters
that are visible to game clients.
Storage (cloud save)
Section titled “Storage (cloud save)”await client.Storage.SaveAsync("save", JsonUtility.ToJson(save));var items = await client.Storage.ReloadAsync();var raw = items.FirstOrDefault(i => i.Type == "save")?.Data;await client.Storage.DeleteAsync("save");One item per player and type; Data is an opaque string.
Modules
Section titled “Modules”Game features are installed modules. Generate a typed client with the
rudder CLI and commit it, for example under Assets/Rudder/:
RUDDER_URL=https://api.rudder.build RUDDER_TOKEN=... RUDDER_PROJECT=... \ rudder client generate --lang csharp --out Assets/Rudder/RudderModules.g.csusing RudderSdk;using RudderSdk.Modules;
var m = new RudderModules(client);try{ var top = await m.Leaderboards.TopAsync(new LeaderboardsTopArgs { Slug = "weekly", Limit = 10 });}catch (RudderModuleException e) when (e.Code == LeaderboardsTopErrors.BoardNotFound){ Debug.LogWarning(e.Message);}There is no editor integration: rerun the command after installing or
upgrading modules. Module calls carry an idempotency key and are retried up to
2 times on network errors, 5xx and 409 conflict. See
Generated module clients.
Errors
Section titled “Errors”Errors are RudderApiException subclasses from RudderSdk:
RudderModuleException (422, module business error with Code),
RudderAuthException (401, the session is over), RudderNotFoundException
(404), RudderRateLimitException (429) and RudderNetworkException (no
response). Each carries StatusCode, Code and RequestId.
Unity notes
Section titled “Unity notes”awaitSDK calls withoutConfigureAwait(false), and never block the main thread on SDK tasks.- There is nothing to dispose in game code.
- Static state resets on domain reload, so Play Mode without domain reload works.
- SDK logs go to
Debug.Log*with a[Rudder]prefix.
Samples
Section titled “Samples”Import Feature Samples from the Package Manager (select the Rudder SDK package, then Samples). Each scene shows one API:
| Scene | SDK calls |
|---|---|
| Authentication | Rudder.Initialize, Auth.LoginWithDeviceAsync, Player.ReloadAsync, Auth.Logout |
| Player | Player.LoadAsync, Player.Changed, Catalog.LoadAsync |
| Storage | Storage.ReloadAsync, SaveAsync, DeleteAsync |
| Modules | a generated RudderModules, RudderModuleException |
Assign a RudderConfiguration on the Rudder object if the field is empty,
then press Play.