Skip to main content

Event Tracking

GameAnalytics features the following event types:

EventDescription
AdAds shown and clicked, fill rate.
BusinessIn-App Purchases supporting receipt validation on GA servers.
DesignSubmit custom event id’s. Useful for tracking metrics specifically needed for your game.
ErrorSubmit exception stack traces or custom error messages.
HealthAutomatically submits health metrics related to your game such as FPS.
ImpressionImpression data from different ad networks
ProgressionLevel attempts with Start, Fail & Complete event.
ResourceManaging the flow of virtual currencies - like gems or lives
tip

Read more about events here

To send an event, remember to include the namespace GameAnalyticsSDK:

using GameAnalyticsSDK;
info

If you are new to GameAnalytics and our Events, please read our event guide here You will get the most benefit of GameAnalytics when understanding what and how to track events.


caution

Remember to only send events from main thread as the SDK internally uses some Unity functions which can only be used from main thread.

Business Events​

FieldTypeDescriptionExample
currencystringCurrency code in ISO 4217 formatUSD
amountintegerAmount in cents99 is $0.99
itemTypestringThe type/category of the itemGoldPacks
itemIdstringSpecific item bought1000GoldPack
cartTypestringThe game location of the purchase. Max 10 unique valuesEndOfLevel

With validation​

Receipt validation in Unity is supported for the following stores:

  • App Store (iOS, tvOS)
  • Google Play Store (Android)

There are two ways to send a validated business event:

  • IAP Validation (SDK 8.3.0 and later): pass the store identifiers of the purchase in a GAReceiptInfo. The same GameAnalytics.NewBusinessEvent call works on every platform.
  • Legacy: pass the store receipt to a platform-specific method.
GameAnalytics.NewBusinessEvent (string currency, int amount, string itemType, string itemId, string cartType, GAReceiptInfo receipt)

Create the GAReceiptInfo for the store the purchase was made in:

GAReceiptInfo receipt = GAReceiptInfo.AppStore(transactionId);
GameAnalytics.NewBusinessEvent("USD", 99, "GoldPacks", "1000GoldPack", "EndOfLevel", receipt);
FieldTypeDescription
transactionIdstringThe App Store transaction ID of the purchase: transactionIdentifier (StoreKit 1) or Transaction.id (StoreKit 2). Cannot be empty.

Retrieving the transaction ID with Unity IAP​

private IStoreController m_StoreController;

public class Receipt
{
public string Store;
public string TransactionID;
public string Payload;
}

//...
public PurchaseProcessingResult ProcessPurchase (PurchaseEventArgs args)
{
//...
var product = m_StoreController.products.WithID(kProductIDConsumable);
string currency = product.metadata.isoCurrencyCode;
int amount = decimal.ToInt32 (product.metadata.localizedPrice * 100);
#if UNITY_IOS
Receipt receiptiOS = JsonUtility.FromJson<Receipt>(product.receipt);
GameAnalytics.NewBusinessEvent(currency, amount, "my_item_type", kProductIDConsumable, "my_cart_type", GAReceiptInfo.AppStore(receiptiOS.TransactionID));
#endif

return PurchaseProcessingResult.Complete;
}
caution

The event is not sent if the GAReceiptInfo does not match the platform (GAReceiptInfo.AppStore on iOS/tvOS, GAReceiptInfo.GooglePlay on Android) or if any of its values are empty. On other platforms the event is sent without validation.

Without Validation​

It is also possible to send business events without validation.

GameAnalytics.NewBusinessEvent (string currency, int amount, string itemType, string itemId, string cartType)

Custom Event Fields​

It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:

Dictionary<string, object> fields = new Dictionary<string, object>();
fields.Add("test", 100);
fields.Add("test_2", "hello_world");

GameAnalytics.NewBusinessEvent(currency, amount, "my_item_type", kProductIDConsumable, "my_cart_type", GAReceiptInfo.AppStore(transactionId), fields);
tip

Find more information on Custom Event Fields and Data Export following the links.

caution

We do not support purchase validation for any of the other platforms listed by Unity IAP (Mac App store or Windows store).


tip

For more information on Business Events go here.

Ad Events​

caution

Ad Events are supported only for the Android and iOS! platforms

tip

To track the revenue of each ad impression automatically from your mediation SDK (LevelPlay, AppLovin MAX, AdMob, etc.), see Ad Revenue (ILRD).


The GameAnalytics ad event needs to be called when certain ad events have been triggered. Ad SDKs usually have callback methods for certain events (like when showing an ar or when an ad has been clicked).


To use the ad event it is need to call the GameAnalytics SDK when these delegates are called. The examples below describe how to implement this for the following ad-types:

  • rewarded video
  • interstitial
  • banner

All code examples use AdMob SDK to showcase example usage.

Other ad networks might differ in naming/structure, but the overall process should be applicable to all.

The ad SDK name argument for the ad event needs to be all lower-case with no spaces or underscore used. Here some examples of valid values to use for ad SDK names:

  • admob
  • unityads
  • ironsource
  • applovin

Rewarded Videos​

Showing a Rewarded video​

It is possible that the ad SDK cannot return an ad for your app. You can track if the rewarded video has failed to show with the following event.

if (this.rewardedAd.IsLoaded()) {
// show the ad
this.rewardedAd.Show();

// send ad event
GameAnalytics.NewAdEvent(GAAdAction.Show, GAAdType.RewardedVideo, "admob", "[AD_PLACEMENT_OR_UNIT_ID]");
}
else
{
GameAnalytics.NewAdEvent(GAAdAction.FailedShow, GAAdType.RewardedVideo, "admob", "[AD_PLACEMENT_OR_UNIT_ID]");
}

Track time spent inside the ad​

If you want to track how much time it took the user to watch the ad you can start a timer and keep track of current rewarded video ad when OnAdOpening delegate is called. The following example is a method for how you could handle this.

public void HandleRewardedAdOpening(object sender, EventArgs args)
{
// keep track of current rewarded video ad
currentRewardedVideoPlacement = "[AD_PLACEMENT_OR_UNIT_ID]";
// start timer for this ad identifier
GameAnalytics.StartTimer(currentRewardedVideoPlacement);
}

// when application goes to background (during the display of a rewarded video ad) then the timer needs to stop.
// therefore we need to call code in Unity method OnApplicationPause.
void OnApplicationPause(bool paused) {
if(paused)
{
if(currentRewardedVideoPlacement != null)
{
GameAnalytics.PauseTimer(currentRewardedVideoPlacement);
}
}
else
{
if(currentRewardedVideoPlacement != null)
{
GameAnalytics.ResumeTimer(currentRewardedVideoPlacement);
}
}
}

Track when the ad has finished​

It is useful to track when the ad has finished and the user returns to the game. For admob this delegate is called OnAdClosed and the following example is a method for how you could handle this.

public void HandleRewardedAdClosed(object sender, EventArgs args) {
if(currentRewardedVideoPlacement != null)
{
long elapsedTime = GameAnalytics.StopTimer(currentRewardedVideoPlacement);
// send ad event for tracking elapsedTime
GameAnalytics.NewAdEvent(GAAdAction.Show, GAAdType.RewardedVideo, "admob", "[AD_PLACEMENT_OR_UNIT_ID]", elapsedTime);
currentRewardedVideoPlacement = null;

// OR if you do not wish to track time

// send ad event without tracking elapsedTime
GameAnalytics.NewAdEvent(GAAdAction.Show, GAAdType.RewardedVideo, "admob", "[AD_PLACEMENT_OR_UNIT_ID]");
}
}

Interstitials​

Showing an Interstitial ad​

As in the example for the rewarded video, you can also send an event when the ad has failed to load.

if (this.interstitial.IsLoaded()) {
// show the ad
this.interstitial.Show();
// send ad event
GameAnalytics.NewAdEvent(GAAdAction.Show, GAAdType.Interstitial,"admob", "[AD_PLACEMENT_OR_UNIT_ID]");
}
else
{
GameAnalytics.NewAdEvent(GAAdAction.FailedShow, GAAdType.Interstitial, "admob", "[AD_PLACEMENT_OR_UNIT_ID]");
}
Closing an Interstitial ad​

This event should be called when the interstitial ad has been finished. The equivalent for the admob sdk is OnAdLeavingApplication.

public void HandleInterstitialLeftApplication(object sender, EventArgs args) {
// send ad event - ad click
GameAnalytics.NewAdEvent(GAAdAction.Clicked, GAAdType.Interstitial,"admob", "[AD_PLACEMENT_OR_UNIT_ID]");
}

Banners​

Showing a Banner Ad​

It is possible to track when a banner ad has been loaded by using the following event. For admob this callback would be used when OnAdLoaded is called.

public void HandleAdLoaded(object sender, EventArgs args) {
GameAnalytics.NewAdEvent(GAAdAction.Show, GAAdType.Banner,"admob", "[AD_PLACEMENT_OR_UNIT_ID]");
}

Track banner clicks​

If you wish to track when an user is clicking on a banner ad you have to use this event. For admob this should be triggered on OnAdOpening.

public void HandleAdOpened(object sender, EventArgs args) {
// send ad event
GameAnalytics.NewAdEvent(GAAdAction.Clicked, GAAdType.Banner, "admob", "[AD_PLACEMENT_OR_UNIT_ID]");
}

Custom Banner Event Fields​

It is possible to append extra information to this event as a map of key-value pairs.

caution

The custom information will only be available through raw data export!

The sample below will show you how to add custom fields:

Dictionary<string, object> fields = new Dictionary<string, object>();
fields.put("test", 100);
fields.put("test_2", "hello_world");

GameAnalytics.NewAdEvent(GAAdAction.Clicked, GAAdType.Banner, "admob", "[AD_PLACEMENT_OR_UNIT_ID], fields");
}
tip

Find more information on Custom Event Fields and Data Export following the links.

Ad Event Info​

In the table below you can find all the values supported for ad events.

FieldTypeDescriptionExample
adActionenumA defined enum for ad action (for example clicked).GAAdAction.Clicked
GAAdAction.Show
GAAdAction.FailedShow
GAAdAction.RewardReceived
adTypeenumA defined enum for ad type (for example interstitial).GAAdType.Video
GAAdType.RewardedVideo
GAAdType.Playable
GAAdType.Interstitial
GAAdType.OfferWall
GAAdType.Banner
adSdkNamestringName of the Ad/Ad mediation SDK.admob
adPlacementstringIdentifier of ad in the game or the placement of it.level_complete_ad
durationintOptional. Only used for video ads to track how long the user watched the video for.10
noAdReasonenumOptional. Used to track the reason for not being able to show an ad when needed (for example no fill).GAAdError.Unknown
GAAdError.Offline
GAAdError.NoFill
GAAdError.InternalError
GAAdError.InvalidRequest
GAAdError.UnableToPrecache
tip

For more information on Ad Events go here.

Impression Events​

Impression events are used to get impression data from different ad networks. Currently the following ad networks are supported:

  • Fyber
  • IronSource
  • TopOn
  • MAX
  • Aequus
  • AdMob

Fyber​

To use impression data from Fyber add the following code inside the Start function and the SDK will then automatically send the impression events for you:

void Start ()
{
// ... code
GameAnalyticsILRD.SubscribeFyberImpressions();
}

IronSource​

To use impression data from IronSource add the following code inside the Start function and the SDK will then automatically send the impression events for you:

void Start ()
{
// ... code
GameAnalyticsILRD.SubscribeIronSourceImpressions();
}

TopOn​

To use impression data from TopOn add the following code inside the Start function and the SDK will then automatically send the impression events for you:

void Start ()
{
// ... code
GameAnalyticsILRD.SubscribeTopOnImpressions();
}

MAX​

To use impression data from MAX add the following code inside the Start function and the SDK will then automatically send the impression events for you:

void Start ()
{
// ... code
GameAnalyticsILRD.SubscribeMaxImpressions();
}

Aequus​

To use impression data from Aequus add the following code inside the Start function and the SDK will then automatically send the impression events for you:

void Start ()
{
// ... code
GameAnalyticsILRD.SubscribeAequusImpressions();
}

AdMob​

To use impression data from AdMob add the following code for each ad you create and the SDK will then automatically send the impression events for you:

// BannerView
bannerView = new BannerView(adUnitId, AdSize.SmartBanner, AdPosition.Top);
GameAnalyticsILRD.SubscribeAdMobImpressions(adUnitId, bannerView);

// InterstitialAd
interstitialAd = new InterstitialAd(adUnitId);
GameAnalyticsILRD.SubscribeAdMobImpressions(adUnitId, interstitialAd);

// RewardedAd
rewardedAd = new RewardedAd(adUnitId);
GameAnalyticsILRD.SubscribeAdMobImpressions(adUnitId, rewardedAd);

// RewardedInterstitialAd
RewardedInterstitialAd.LoadAd(adUnitId, CreateAdRequest(), (rewardedInterstitialAd, error) =>
{
if(error == null)
{
GameAnalyticsILRD.SubscribeAdMobImpressions(adUnitId, rewardedInterstitialAd);
}
});
tip

For more information on Impression Events go here.

Resource Events​

Resource events are used to track the flow of resources in your game.

info

Before you start sending resource events you need to set up the currencies and item types in the GameAnalytics settings, as described here.

To add a resource event call the following function:

GameAnalytics.NewResourceEvent (GA_Resource.GAResourceFlowType flowType, string currency, float amount, string itemType, string itemId)
FieldTypeRequiredDescription
flowTypeenumyesAdd (source) or subtract (sink) resource.
currencystringyesOne of the available currencies set in GA_Settings (Setup tab).This string can only contain [A-Za-z] characters.
amountfloatyesAmount sourced or sunk.
itemTypestringyesOne of the available item types set in GA_Settings (Setup tab).
itemIdstringyesItem id (string max length = 32)

caution

Be careful to not call the resource event too often! In a game where the user collect coins fairly fast you should not call a Source event on each pickup.

Instead you should count the coins and send a single Source event when the user either completes or fails the level.


Here are some examples and best practices for structuring the events:

GameAnalytics.NewResourceEvent(GA_Resource.GAResourceFlowType.GAResourceFlowTypeSource, “Gems”, 400, “IAP”, “Coins400”);

GameAnalytics.NewResourceEvent(GA_Resource.GAResourceFlowType.GAResourceFlowTypeSink, “Gems”, 400, “Weapons”, “SwordOfFire”);

GameAnalytics.NewResourceEvent(GA_Resource.GAResourceFlowType.GAResourceFlowTypeSink, “Gems”, 100, “Boosters”, “BeamBooster5Pack”);

GameAnalytics.NewResourceEvent(GA_Resource.GAResourceFlowType.GAResourceFlowTypeSource, “BeamBooster”, 5, “Gems”, “BeamBooster5Pack”);

GameAnalytics.NewResourceEvent(GA_Resource.GAResourceFlowType.GAResourceFlowTypeSink, “BeamBooster”, 3, “Gameplay”, “BeamBooster5Pack”);

Custom Resource Event Fields​

It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:

Dictionary<string, object> fields = new Dictionary<string, object>();
fields.put("test", 100);
fields.put("test_2", "hello_world");

GameAnalytics.NewResourceEvent(GA_Resource.GAResourceFlowType.GAResourceFlowTypeSink, “BeamBooster”, 3, “Gameplay”, “BeamBooster5Pack”, fields);
tip

Find more information on Custom Event Fields and Data Export following the links.

Progression Events​

Progression events are used to track user's progression in the game, for example a new level, high score or dungeon. In the unity sdk you can register such events with the following api:

// Using 1 progression part (01) and no score
GameAnalytics.NewProgressionEvent(GA_Progression.GAProgressionStatus progressionStatus, string progression01)

// Using 1 progression part (01) and score
GameAnalytics.NewProgressionEvent(GA_Progression.GAProgressionStatus progressionStatus, string progression01, int score)

// Using 2 progression parts (01+02) and no score
GameAnalytics.NewProgressionEvent(GA_Progression.GAProgressionStatus progressionStatus, string progression01, string progression02)

// Using 2 progression parts (01+02) and score
GameAnalytics.NewProgressionEvent(GA_Progression.GAProgressionStatus progressionStatus, string progression01, string progression02, int score)

// Using 3 progression parts (01+02+03) and no score
GameAnalytics.NewProgressionEvent(GA_Progression.GAProgressionStatus progressionStatus, string progression01, string progression02, string progression03, int score)

// Using 3 progression parts (01+02+03) and score
GameAnalytics.NewProgressionEvent(GA_Progression.GAProgressionStatus progressionStatus, string progression01, string progression02, string progression03, int score)

The progression event accepts the following parameters:

FieldTypeRequiredDescription
progressionStatusenumyesStatus of added progression (start, complete, fail).
progression01stringyes1st progression (e.g. world01).
progression02stringno2nd progression (e.g. level01).
progression03stringno3rd progression (e.g. phase01).
scoreintnoThe player’s score.

If you do not need progression02 or progression03 do not make any references to these parameters when calling the method. Below you can learn from an example of progression event that uses only progression01 and progression02:

GameAnalytics.NewProgressionEvent (GAProgressionStatus.Start, "World1");
GameAnalytics.NewProgressionEvent (GAProgressionStatus.Complete, "World1", score);
GameAnalytics.NewProgressionEvent (GAProgressionStatus.Start, "World1", "Level1");
GameAnalytics.NewProgressionEvent (GAProgressionStatus.Complete, "World1", "Level1", score);
GameAnalytics.NewProgressionEvent (GAProgressionStatus.Start, "World1", "Level1", "Phase1");
GameAnalytics.NewProgressionEvent (GAProgressionStatus.Complete, "World1", "Level1", "Phase1", score);

Error Events​

To add a custom error event you can call the following function:

GameAnalytics.NewErrorEvent (GAErrorSeverity severity, string message)

The arguments for this event are described below:

FieldTypeRequiredDescriptionExample
severityenumyesSeverity of error (critical, debug, error, info, warning).GAErrorSeverity.Warning
messagestringyesErrormessage (Optional, can be null).

Custom Error Event Fields​

It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:

Dictionary<string, object> fields = new Dictionary<string, object>();
fields.put("test", 100);
fields.put("test_2", "hello_world");

GameAnalytics.NewErrorEvent (severity, message, fields);

Find more information on Custom Dimensions and Data Export following the links.

Design Events​

To add a design event call the following function:

GameAnalytics.NewDesignEvent (string eventName, float eventValue)
FieldTypeRequiredDescription
eventNamestringyesThe event string can have 1 to 5 parts. The parts are separated by ‘:’ with a max length of 64 each. e.g. “world1:kill:robot:laser”. The parts can be written only with a-zA-Z, 0-9, -_.,:()!? characters.
eventValuefloatnoNumber value of event.

Custom Design Event Fields​

It is possible to use a set of key-value pairs to add extra fields but it will only be available through raw data export. Here is an example of how to use it:

Dictionary<string, object> fields = new Dictionary<string, object>();
fields.put("test", 100);
fields.put("test_2", "hello_world");

GameAnalytics.NewDesignEvent (eventName, eventValue, fields);

Find more information on Custom Event Fields and Data Export following the links.