Unity SDK
The Amplitude Analytics Unity SDK is a plugin that simplifies the integration of Amplitude iOS and Android SDKs into your Unity project. This SDK works with Unity 2019.3.11 and higher.
Supported platforms
Unity SDK doesn't support pure desktop or Editor.
Test your apps using the Build Settings for either Android or iOS, which links to their respective devices or emulators.
Install the SDK
The Amplitude Analytics Unity SDK supports different installation methods, depending on the platform.
Option 1: Unity Package Manager
- Make sure you have Git installed.
- In Unity, click Window > Package Manager.
- Click the plus + sign and select Add package from Git URL.
- Enter
https://github.com/amplitude/unity-plugin.git?path=/Assets, and then click Add. - The Unity editor imports the package from Git.
Option 2: Manual download
- Download the latest
amplitude-unity.unitypackagefrom GitHub releases. - Double click
amplitude-unity.unitypackageto import the package into your Unity project.
Android
Add obfuscation exception
Add this line in your ProGuard rules file, proguard.pro.
-keep class com.amplitude.unity.plugins.AmplitudePlugin { *; }
Dependency management
Amplitude's com.amplitude.android-sdk is a transitive library, and it doesn't include any other dependencies by itself. Amplitude places other dependencies for com.amplitude.android-sdk into Assets/Plugins/Android. Amplitude uses OkHTTP, and the other dependencies you see are ones OkHTTP depends on (for example, Okio or Jetbrains).
If you use OkHTTP in your project, you can choose not to include OkHTTP and its related dependencies by unchecking them.
Use unity-jar-resolver
Some users use unity-jar-resolver themselves. When they force resolve dependencies, unity-jar-resolver cleans up Amplitude-related jars. In this case, declare those dependencies in your *Dependencies.xml file.
Add Amplitude's native dependencies under the androidPackage tag.
<androidPackage spec="com.amplitude:android-sdk:2.+">
<repositories>
<repository>https://maven.google.com</repository>
</repositories>
</androidPackage>
<androidPackage spec="com.squareup.okhttp3:okhttp:4.2.2">
<repositories>
<repository>https://maven.google.com</repository>
</repositories>
</androidPackage>
API compatibility
The Amplitude Analytics Unity SDK depends on the OkHTTP library. OkHTTP v3.13 requires a minimum Android version of Android 5.0, Android Lollipop (API 21). For more information, refer to OkHttp 3.13 requires Android 5+.
Amplitude doesn't restrict which OkHTTP version to use. For API 19, 20 (Android KitKat) to work, downgrade the OkHTTP version to be lower than 3.13.
- Change the version of OkHTTP to be lower than 3.13.
- In Unity, import the library by copying the .jar file. You can downgrade the OkHTTP library by replacing it with a version lower than 3.13. If you use Google dependency resolver, update the dependency version for OkHTTP in your
*Dependency.xmlfile.
iOS XCode troubleshooting
If Xcode doesn't let you use a simulator or device, it's because you must configure the Unity project to use either the Device SDK (physical devices) or the Simulator SDK (emulator).
To change the settings for the build, select Unity > Edit > Project Settings... > Player > iOS Tab, open the Other Settings dropdown menu, scroll to Configuration, and select either value needed for the Target SDK field.
Initialize the SDK
Initialize the SDK before you can do instrumentation. The API key for your Amplitude project is required.
Amplitude amplitude = Amplitude.getInstance();
amplitude.setServerUrl("https://api2.amplitude.com");
amplitude.logging = true;
amplitude.trackSessionEvents(true);
amplitude.init(AMPLITUDE_API_KEY);
Optionally, you can send a string instanceName to getInstance(). This string associates with all the settings of one Amplitude object.
Amplitude amplitude1 = Amplitude.getInstance("client_1");
Amplitude amplitude2 = Amplitude.getInstance("client_2");
//Settings changes in amplitude1 will not be reflected in amplitude2
Amplitude.getInstance("client_1") //this is the same reference as amplitude1
Configure the SDK
Amplitude Unity SDK runs on top of the Amplitude Android Maintenance SDK, and Amplitude iOS Maintenance SDK. The following are the C# settable config options.
For other default configurations:
- On Android, refer to Android Configuration.
- On iOS side, refer to iOS configuration.
| Name | Description | Default Value |
|---|---|---|
enableCoppaControl() | Enable COPPA (Children's Online Privacy Protection Act) restrictions on IDFA, IDFV, city, IP address and location tracking. | Coppa control is disabled by default. |
disableCoppaControl() | Disable COPPA (Children's Online Privacy Protection Act) restrictions on IDFA, IDFV, city, IP address and location tracking. | Coppa control is disabled by default. |
setTrackingOptions() | IDictionary<string, bool>. By default, the SDK tracks several user properties such as carrier, city, country, ip_address, language, platform, etc. | All tracking options enabled. |
setMinTimeBetweenSessionsMillis() | long. The amount of time for session timeout if you disable foreground tracking. For example, Amplitude.getInstance().setMinTimeBetweenSessionsMillis(100000). The input parameter is in milliseconds. | 5 minutes |
setEventUploadPeriodSeconds() | int. Events wait in the buffer and Amplitude sends them in a batch. The SDK flushes the buffer every eventUploadPeriodSeconds or when it reaches the 30 events threshold. For example, Amplitude.getInstance().setEventUploadPeriodSeconds(50). The input parameter is in seconds. | 30 seconds |
setServerZone() | AmplitudeServerZone. The server zone of the projects. Supports EU and US. For EU data residency, change to EU. For example, Amplitude.getInstance().setServerZone(AmplitudeServerZone.US). | AmplitudeServerZone.US |
setServerUrl() | string. The API endpoint URL that the SDK sends events to. ServerZone selects this automatically. For example, Amplitude.getInstance().setServerUrl(https://www.your-server-url.com). | https://api2.amplitude.com/ |
setUseDynamicConfig() | bool. Finds the best server URL automatically based on users' geographic location. For example, Amplitude.getInstance().setUseDynamicConfig(true). | false |
setOffline() | bool. Whether the SDK uploads events to Amplitude servers. The SDK always logs events. For example, Amplitude.getInstance().setOffline(true). | false |
useAdvertisingIdForDeviceId() | bool. Whether to use advertising id as device id. Refer to the Advertiser ID docs for the required module and permission. For example, Amplitude.getInstance().useAdvertisingIdForDeviceId(true). | The deviceId is UUID+"R" by default. |
useAppSetIdForDeviceId() | bool. Only for Android. Whether to use app set id as a deviceId. Refer to the App Set ID docs for the required module and permission. For example, Amplitude.getInstance().useAppSetIdForDeviceId(true). | The deviceId is UUID+"R" by default. |
Configure batching behavior
To support high-performance environments, the SDK sends events in batches. The SDK queues every event logged by the logEvent method in memory. The SDK flushes events in batches in the background. You can customize batch behavior with setEventUploadPeriodSeconds. By default, the serverUrl is https://api2.amplitude.com/. This SDK doesn't support batch mode through the batch API endpoint.
// Events queue flushes every certain seconds based on setting
// Default value is 30 seconds
amplitude.setEventUploadPeriodSeconds(50);
EU data residency
Starting from version 2.4.0, you can configure the server zone after initializing the client to send data to Amplitude's EU servers. The SDK switches and sends data based on the server zone if it's set. The server zone configuration also supports dynamic configuration.
For earlier versions, you need to configure the serverURL property after initializing the client.
For EU data residency, configure your project inside Amplitude EU and initialize the SDK with an API key from Amplitude EU first. This method doesn't work without proper setup first.
// For versions starting from 2.4.0
// No need to call setServerUrl for sending data to Amplitude's EU servers
amplitude.setServerZone(AmplitudeServerZone.EU);
// For earlier versions
amplitude.setServerUrl("https://api.eu.amplitude.com");
Send basic events
Events represent how users interact with your application. For example, "Button Clicked" might be an action you want to note.
amplitude.logEvent("Button Clicked");
When running this in Unity, make sure that you have iOS or Android selected in the Build Settings under Platform.
Send events with properties
Events can also contain properties. Properties give context about the event taken. For example, "hover time" might be a relevant event property to "button click".
Dictionary<string, object> eventProps = new Dictionary<string, object>();
eventProps.Add("Hover Time", 10);
amplitude.logEvent("Button Clicked", eventProps);
Set user properties
Privacy and tracking
Don't track any user data that might be against your privacy terms. If you need assistance with privacy concerns, contact the Amplitude Platform team.
Identify
Identify is for setting the user properties of a particular user without sending any event. The Unity SDK supports the operations setUserProperty, setOnce, add, and append on individual user properties.
Declare the operations with a provided Identify interface. Chain together multiple operations in a single Identify object. Pass the Identify object to the Amplitude client to send to the server.
Identify call
If you send the Identify call after the event, the results of operations appear immediately in the dashboard user's profile area, but they don't appear in chart results until you send another event after the Identify call. The identify call only affects events going forward. For more details, refer to User properties and events.
Manage user identity
You can handle the identity of a user using the identify methods. Proper use of these methods can connect events to the correct user as they move across devices, browsers, and other platforms.
Send an identify call containing those user property operation to Amplitude to tie a user's events with specific user properties.
setUserProperty
setUserProperty sets the value of a user property. You can also chain together multiple identify calls.
amplitude.setUserProperty("saw_page_a", true);
setOnce
setOnce sets the value of a user property only once. The SDK ignores subsequent calls using setOnce.
amplitude.setOnceUserProperty("page_views", 50);
add
add increments a user property by some numerical value. If the user property doesn't have a value set yet, the SDK initializes it to 0.
amplitude.addUserProperty("oranges", 5);
Dictionary<string, object> values = new Dictionary<string, object>();
values.Add("Key A", "Value A");
amplitude.addUserPropertyDict("user_facts", values);
Set multiple user properties
logEvent() method lets you set the user properties along with event logging. You can use setUserProperties as a shorthand to set multiple user properties at once. This method is a wrapper around Identify.set.
Dictionary<string, object> values = new Dictionary<string, object>();
values.Add("user_time", 100.5);
values.Add("engagement", true);
amplitude.setUserProperties(values);
Arrays in user properties
You can use arrays as user properties. You can directly set arrays or use append to generate an array.
int[] arr = new int[] { 1, 2, 4, 8 };
amplitude.setUserProperty("user_running_times", arr);
append
append appends a value or values to a user property array. If the user property doesn't have a value set yet, the SDK initializes it to an empty list before adding the new values. If the user property has an existing value and it's not a list, the SDK converts the existing value into a list and adds the new value.
amplitude.setUserProperty("stringArray", new string[]{"replace", "existing", "strings"});
amplitude.appendUserProperty("stringArray", new string[]{ "append", "more", "strings" });
Clear user properties
clearUserProperties method is for clearing all user properties at one time.
Clearing user properties is irreversible
Amplitude doesn't sync the user's user property values before the wipe to any future events that the user triggers, because the SDK has reset them.
amplitude.clearUserProperties();
unset
unset unsets and removes a user property.
amplitude.unsetUserProperty("property_name_to_unset");
Set user groups
Amplitude supports assigning users to groups and performing queries, such as Count by Distinct, on those groups. If at least one member of the group has performed the specific event, then the count includes the group.
For example, you want to group your users based on what organization they're in by using an 'orgId'. Joe is in 'orgId' '10', and Sue is in 'orgId' '15'. Sue and Joe both perform a certain event. You can query their organizations in the Event Segmentation Chart.
When setting groups, define a groupType and groupName. In the previous example, 'orgId' is the groupType and '10' and '15' are the values for groupName. Another example of a groupType could be 'sport' with groupName values like 'tennis' and 'baseball'.
Setting a group also sets the groupType:groupName as a user property, and overwrites any existing groupName value set for that user's groupType, and the corresponding user property value. groupType is a string, and groupName can be either a string or an array of strings to indicate that a user is in multiple groups.
This example shows a groupType "orgID" with a groupName of "15". The second line shows a groupType "sport" with "tennis" and "soccer" as groupNames.
Amplitude.getInstance().setGroup("orgId", "15");
Amplitude.getInstance().setGroup("sport", new JSONArray().put("tennis").put("soccer")); // list values
You can also use logEventWithGroups to set event-level groups. The group designation only applies for the specific event you log, and doesn't persist on the user unless you explicitly set it with setGroup:
JSONObjecteventProperties=newJSONObject().put("key", "value");
JSONObjectgroups=newJSONObject().put("orgId", 10);
Amplitude.getInstance().logEvent("initialize_game", eventProperties, groups);
Track revenue
Amplitude can track revenue generated by a user. Amplitude tracks revenue through distinct revenue objects, which have special fields that Amplitude's Event Segmentation and Revenue LTV charts use. Amplitude automatically displays data relevant to revenue in the platform. Revenue objects support the following special properties, as well as user-defined properties through the eventProperties field.
Calling logRevenue generates up to 2 different event types in the platform:
- '[Amplitude] Revenue': Amplitude logs this event for all revenue events, regardless of whether verification is turned on.
- '[Amplitude] Revenue (Verified/Unverified)': These revenue events contain the actual '$revenue' property.
You can't change the default names given to these client-side revenue events in the raw data, but you can modify the display name. To learn more about tracking revenue, refer to the Track revenue documentation.
| Name | Description |
|---|---|
productId | Optional. String. An identifier for the product. Amplitude recommends something like the "Google Play Store product ID". Defaults to null. |
quantity | Required. Integer. The quantity of products purchased. revenue = quantity * price. Defaults to 1. |
price | Required. Double. The price of the products purchased, and this can be negative. revenue = quantity * price. Defaults to null. |
revenueType | Optional, but required for revenue verification. String. The type of revenue (for example, tax, refund, income). Defaults to null. |
eventProperties | Optional. Object. An object of event properties to include in the revenue event. Defaults to null. |
Price can be negative, which might be useful for tracking revenue lost (such as refunds or costs).
Verify revenue
Because Unity supports both the Android and iOS stores, consult the proper documentation for revenue verification. Refer to the Android and iOS/tvOS/macOS documentation, and special instructions for the store (Android AIDL/Google Play Billing, Amazon Store, or iOS App Store).
amplitude.logRevenue(0.03);
amplitude.logRevenue("sku", 1, 1.99);
amplitude.logRevenue("sku", 1, 1.99, "cmVjZWlwdA==", null);
Dictionary<string, object> revenueProperties = new Dictionary<string, object>()
{
{"car", "blue"},
{"price", 12.99}
};
if (Application.platform == RuntimePlatform.IPhonePlayer) {
amplitude.logRevenue("sku", 1, 1.99, "cmVjZWlwdA==", null, "purchase", revenueProperties);
} else if (Application.platform == RuntimePlatform.Android) {
amplitude.logRevenue("sku", 1, 1.99, "receipt", "receiptSignature", "purchase", revenueProperties);
}
Amplitude doesn't support currency conversion. Normalize all revenue data to your currency of choice before sending.
User sessions
A session on Android is a period of time that a user has the app in the foreground.
Amplitude groups events together by session. Events logged within the same session have the same session_id. Amplitude handles sessions automatically, so you don't have to manually call an API like startSession() or endSession().
You can adjust the time window for which Amplitude extends sessions.
client.setMinTimeBetweenSessionsMillis(10000); //10 seconds
By default, the SDK doesn't send '[Amplitude] Start Session' and '[Amplitude] End Session' events. Even though the SDK doesn't send these events, Amplitude still tracks sessions by using session_id. To re-enable those session events, add this line before initializing the SDK.
Amplitude amplitude = Amplitude.Instance;
amplitude.trackSessionEvents(true);
amplitude.init(AMPLITUDE_API_KEY);
You can also log events as out-of-session. Internally (in Amplitude dashboards), out-of-session events have a session_id of -1 and aren't part of the current session, meaning they don't extend the current session. This might be useful if you're logging events triggered by push notifications, for example. You can log events as out-of-session by setting the input parameter outOfSession to true when calling logEvent().
Dictionary<string, object> eventProps = new Dictionary<string, object>();
bool outOfSession = true;
client.logEvent("event out of session", eventProps, outOfSession);
Advertising ID
Advertiser ID (also referred to as IDFA) is a unique identifier provided by the iOS and Google Play stores. Because it's unique to every person and not only their devices, IDFA is useful for mobile attribution. Mobile attribution is the attribution of an installation of a mobile app to its original source (for example, ad campaign, app store search).
Mobile apps need permission to ask for IDFA, and apps targeted to children can't track at all. Consider IDFV, device id, or an email login system as alternatives when IDFA isn't available.
iOS setup
For setup instructions, refer to Unity iOS IDFA and GPS Setup.
Android setup
For setup instructions, refer to the Android SDK.
Location tracking
For location tracking, Amplitude converts the IP of a user event into a location (GeoIP lookup) by default. An app's own tracking solution or user data can override this information.
Amplitude can access the Android location service (if possible) to add the specific coordinates (longitude and latitude) where the SDK logs an event.
Set custom user ID
If your app has its own login system that you want to track users with, you can call setUserId at any time.
Amplitude.Instance.setUserId("USER_ID");
You can also add the User ID as an argument to the init call.
Amplitude.Instance.init(AMPLITUDE_API_KEY, "USER_ID");
Don't assign users a User ID that could change, because Amplitude interprets each unique User ID as a unique user. For more information, refer to Track unique users in Amplitude.
Advanced topics
COPPA control
You can enable or disable COPPA (Children's Online Privacy Protection Act) restrictions on IDFA, IDFV, city, IP address, and location tracking all at once. Apps asking for information from children under 13 years of age must comply with COPPA.
client.enableCoppaControl();
Opt out of tracking
Users might want to opt out of tracking entirely, which means no events and no records of their browsing history. This API provides a way to fulfill certain users' requests for privacy.
client.setOptOut(true); //No events are tracked for this user
Dynamic configuration
Unity SDK lets users configure their apps to use dynamic configuration. This feature finds the best Amplitude server URL automatically based on the user's location.
- If you have your own proxy server and use the
setServerUrlAPI, don't use dynamic configuration. - If you have users in Mainland China, Amplitude recommends that you use dynamic configuration.
- By default, this feature is off. You must explicitly enable it to use it.
- By default, this feature returns server URLs for Amplitude's US servers. If you need to send data to Amplitude's EU servers, use
setServerZoneto set it to EU zone.
amplitude.setUseDynamicConfig(true);
iOS IDFA and GPS setup
This section walks through the process to give Unity SDK users access to IDFA (advertiser ID) and GPS coordinate data in their logged events.
Considerations
- This functionality isn't included in the Unity SDK because the Apple App Store flags any app that uses IDFA code, even if the code is disabled or sourced from a third-party SDK developer like Amplitude.
- Consider alternatives to IDFA. Don't assume users enable IDFA tracking; opt-in systems engage less. Use device id, IDFV, or pass your own app's email login system as a custom user property.
- You can edit the Objective-C iOS logic to fetch IDFA and GPS data. However, the current code handles permissions, and accurately updates the IDFA and GPS data within the SDK when the app user gives permissions.
Setup
iOS App Store compliance
If an app is subject to COPPA because it's aimed toward children, the app can't contain any IDFA or GPS tracking code. The IDFA and GPS code requires additional setup for this reason.
First, take the two files unity-plugin/IdfaIOS/CustomIdfa.m and unity-plugin/IdfaIOS/CustomGPS.m and place them into Assets/Scripts. You can place the file wherever, but check that all the #import statements lead to correct paths.
In the imports section (the top) of your .cs game script, add this import:
#if (UNITY_IPHONE || UNITY_TVOS)
using System.Runtime.InteropServices;
#endif
Inside the game class, add the following code inside your MonoBehavior class, or any other class.
public class AmplitudeDemo : MonoBehavior {
#if (UNITY_IPHONE || UNITY_TVOS)
[DllImport ("__Internal")]
private static extern void setIdfaBlock(string instanceName);
[DllImport ("__Internal")]
private static extern void setLocationInfoBlock(string instanceName);
#endif
Finally, in your game code, probably in void Start(), call these functions. YOUR_INSTANCE_NAME is a string associated with this particular instance of Amplitude. YOUR_INSTANCE_NAME can also be null or an empty string.
Amplitude amplitude = Amplitude.getInstance(YOUR_INSTANCE_NAME);
amplitude.init(AMPLITUDE_API_KEY);
#if (UNITY_IPHONE || UNITY_TVOS)
setLocationInfoBlock(YOUR_INSTANCE_NAME);
setIdfaBlock(YOUR_INSTANCE_NAME);
#endif
These functions prompt the iOS user to accept or reject permissions for GPS location tracking, as well as IDFA tracking.
Your Unity app needs two special configurations.
For location, navigate to Unity > Edit > Project Settings.... The menu in the first image below pops up. Select Player, then click the iOS tab. Click Other Settings, and scroll until the Location Usage Description field. Type a sentence that prompts the user for GPS tracking permissions into the text box.
XCode simulator
You can generally test IDFA tracking permissions reliably only on physical phones.
For IDFA, edit the Info.plist file according to Apple's specifications. You can do this with a Unity script with guidance from this Unity post.
Also, when Unity compiles the app into iOS and launches into Xcode, find the top-level file Info.plist. Click the plus symbol next to any key value pair. Use the Xcode editor to find the key Privacy - Tracking Usage Description, make sure the Type is String, and type a prompt to ask for tracking permission in the Value field.
Was this helpful?