Analytics in Unity
Hiro’s analytics system lets your Unity client capture player behavior as events and forward those events to one or more analytics providers: services like Satori , Firebase, GameAnalytics, or Smartlook that receive your events. Each provider is a Hiro integration you add to your systems, so you can send the same event to several services without writing separate tracking code for each.
This page covers the client-side analytics that your Unity game sends. Hiro also emits server-side events from systems such as economy, achievements, and challenges. To learn more, see About Hiro analytics .
How it works #
You send analytics through a single object, systems.AnalyticsGroup. Call one of its methods and it forwards the event to every provider you’ve registered, so you write your tracking once and it reaches all of them. Register your providers once at startup, then call AnalyticsGroup from anywhere in your game.
systems.AnalyticsGroup, not through a provider directly. That reaches every provider at once and gives you the convenience methods like ScreenViewed. Use a provider instance directly only for provider-specific features, for example SatoriSystem for Satori feature flags and live events.Register analytics providers #
Create each provider and add it to Systems. The examples below assume you’ve already done the initial scaffolding as shown in Set up Hiro with Nakama
.
| |
Hiro ships with four built-in analytics providers: Satori, Firebase, GameAnalytics, and Smartlook. Firebase, GameAnalytics, and Smartlook wrap Unity-native SDKs, so add each one only after you install and configure the corresponding SDK in your project.
Satori #
SatoriSystem sends events to the Satori LiveOps platform
, where it powers player segmentation, remote configuration, metrics, and more. It takes a Satori server key and an authorization function that returns a Satori session. Pass null to authorize with the default strategy, or supply your own function to reuse an existing session.
| |
Set useCache to true to store events locally while the device is offline and send them once connectivity returns.
Firebase #
FirebaseSystem sends events into a configured Firebase instance and also handles Firebase Remote Config and Crashlytics. Provide a Firebase configuration JSON file
in your project. The constructor takes the Remote Config fetch interval in seconds.
| |
GameAnalytics #
GameAnalyticsSystem sends events into a configured GameAnalytics
instance.
| |
Smartlook #
SmartlookSystem sends events into a configured Smartlook
instance for session recording and analytics.
| |
IAnalyticsSystem and does not receive events through AnalyticsGroup. AppsFlyer is not a built-in analytics provider. To send events to either service, create a custom provider
.Send events #
Call a convenience method on the group to send a preformatted event to every registered provider:
| |
Every convenience method has a synchronous variant and an Async variant. Use the synchronous variant for fire-and-forget events, and await the Async variant when you need the send to complete:
| |
Default client events #
Each convenience method sends a fixed event name and a set of properties. Use these across your game so every provider receives a consistent, predictable schema.
| Method | Event name | Properties |
|---|---|---|
AchievementClaimed | achievementClaimed | id |
AchievementUpdated | achievementUpdated | id, count |
AdImpression | adImpression | format, source, platform, unitName, id, currency, amount, test |
AdPlacementStarted | adPlacementStarted | id |
AdPlacementSucceeded | adPlacementSucceeded | id |
AdPlacementFailed | adPlacementFailed | id |
AdStarted | adStarted | id |
AppLaunched | appLaunched | (none) |
CurrencyGranted | currencyGranted | name, amount |
CurrencySpent | currencySpent | name, amount |
EnergyGranted | energyGranted | name, amount |
EnergySpent | energySpent | name, amount |
GameStarted | gameStarted | name |
GameFinished | gameFinished | name |
ItemGranted | itemGranted | name, amount |
ItemSpent | itemSpent | name, amount |
ItemConsumed | itemConsumed | name, amount |
PurchaseIntent | purchaseIntent | id, product, sku, store, testPurchase, source |
PurchaseCompleted | purchaseCompleted | id, product, sku, store, transactionId, testPurchase, source |
ScreenViewed | screenViewed | screenName, screenBeforeName |
StatUpdated | statUpdated | name, amount |
TutorialAccepted | tutorialAccepted | name |
TutorialDeclined | tutorialDeclined | name |
TutorialStarted | tutorialStarted | name |
TutorialStepCompleted | tutorialStepCompleted | name, stepIndex |
TutorialCompleted | tutorialCompleted | name |
TutorialAbandoned | tutorialAbandoned | name |
Add metadata to a default event #
Every convenience method accepts an optional metadata dictionary. Hiro merges those entries into the event alongside the standard fields, so you can attach extra context without leaving the standard event set:
| |
Custom events #
Call Event or EventAsync to send an event that isn’t one of the built-in events:
| |
Create a custom provider #
To send events to a service Hiro doesn’t ship with, implement IAnalyticsSystem. Extend BaseAnalyticsSystem to inherit every convenience method and implement only EventAsync and SetUser:
| |
Add your provider to the Systems container like any other, and it joins AnalyticsGroup automatically:
| |
Verify your events #
To confirm your events arrive, open the dashboard of whichever provider you registered and check its incoming event stream.
For Satori, each event appears in the player’s event history, and its name must match an entry under Taxonomy > Events to be retained. To learn how Satori structures events and turns them into properties and metrics, read Understand events .
