This document explains how to download, setup, and use the Unity SDK for Countly. You can download the latest release from Github.
Older documentation
To access the documentation for version 19.09 and older, click here.
The following are some of the key assumptions being considered while developing the SDK. Please take into account the following before integrating this SDK:
- Scripting version is based on .NET 4.x equivalent
- API Compatibility Level is based on .NET 4.x
Integration
Download the Unity package from GitHub and import it into your project.
Adding Write Permission
If you expect the game to be saved on an SD card or any other type of external storage, set Write Permission to 'External (SDCard). This can be found in your Android platform settings under 'Other Settings'.
For more information, check the sample app on Github.
Setting up the SDK
Prefabs are stored in the Assets\Plugins\Countly\Prefabs folder. Select the Countly prefab and in the inspector view, add serverUrl and appKey.
serverUrl - (Mandatory, string) The URL of the Countly server where you are going to post your requests. Example: https://try.count.ly/
Which server/hostname should I use inside the SDK?
If you are using Countly Enterprise trial servers, use the corresponding server name, such as https://try.count.ly, https://us-try.count.ly or https://asia-try.count.ly.
If you use Countly Lite and Countly Enterprise, use your domain name.
appKey - (Mandatory, string) The “App Key” for the app that you created on the Countly server. Example: 124qw3er5u678qwef88d6123456789qwertyui123.
deviceId - (Optional, string) Your Device ID. It is an optional parameter. Example: f16e5af2-8a2a-4f37-965d-qwer5678ui98.
To change the Configuration, update the parameter values.
Below you can find details of each parameter:
salt - (Optional, string) Used to prevent parameter tampering. The default value is NULL.
enablePost - (bool) When set to true, all requests made to the Countly server will be done using HTTP POST. Otherwise, the SDK sends all requests using the HTTP GET method. In some cases, if the data to be sent exceeds the 1800-character limit, the SDK uses the POST method. The default value is false.
enableTestMode - (Optional, bool) This parameter is useful in development when you don't want to send requests to the Countly server. The default value is false.
enableConsoleLogging - (Optional, bool) This parameter is useful when you are debugging your application. When set to true, it basically turns on Logging.
ignoreSessionCooldown - (Optional, bool) Turns on/off the session cooldown behavior. The default value is false.
sessionDuration - (Optional, int) Sets the interval (in seconds) after which the application will automatically extend the session, providing the manual session is disabled. This interval is also used to process requests in the queue. The default value is 60 (seconds).
eventThreshold - (Optional, int) Sets a threshold value that limits the number of events that can be recorded internally by the system before they can all be sent together in one request. Once the threshold limit is reached, the system groups all recorded events and sends them to the server. The default value is 100.
storedRequestLimit - (Optional, int) Sets a threshold value that limits the number of requests that can be stored internally by the system. The system processes these requests after every sessionDuration interval has passed. The default value is 1000.
notificationMode - (Optional, enum) When None, the SDK disables Push Notifications for the device. Use an iOS Test Token or an Android Test Token for testing purposes and in production use a Production Token. The SDK uses the supplied mode for sending Push Notifications. The default value is None.
enableAutomaticCrashReporting - (Optional, bool) Used to turn on/off Automatic Crash Reporting. When set to true, the SDK will catch exceptions and automatically report them to the Countly server. The default value is true.
Initializing the SDK
To start using Countly, you need to attach a script to any GameObject in your scene. Add a public field of type Countly in this script and assign the Countly prefab to this field. Prefabs are stored in the Prefabs folder.
Instantiate the Countly prefab in the awake method.
public Countly countlyPrefab;
private Countly countly;
void Awake ()
{
countly = Instantiate(countlyPrefab);
}
Accessing Countly Global Instance
To access the Countly Global Instance use the following code snippet:
Countly.Instance.
Session handling
The Unity SDK handles the session automatically.
Begin Session: the SDK is responsible for automatically handling the Countly session in your app. As soon as you call the initialization methods (Begin and SetDefaults) in your app start event, the SDK will start the session automatically (only when you set enableManualSessionHandling
to true during initialization).
Update Session: the SDK is responsible for automatically extending the session after every 60 seconds (default value). This value is configurable during initialization using the parameter sessionDuration. It cannot be modified after initialization.
Note that in iOS, the session will not be extended when the app is in the background. As soon as the user switches back to the app, the session extension will resume. In Android, the session will extend on both occasions: foreground and background.
End Session: the SDK is responsible for automatically ending the session whenever the user quits the application.
The Session will be ended automatically when the user calls Application.Quit().
Events
Setting up events
An event is any type of action that you can send to a Countly instance, e.g., purchases, changed settings, view enabled, and so on, letting you get valuable information about your application.
The Unity SDK helps record as many events as you want (you can set a threshold limit during initialization), and the system will send them automatically to the server once the threshold limit is reached. By default, Countly tracks only up to 100 events. However, this is also configurable.
Accessing event-related functionalities
In the SDK, all event-related functionalities can be browsed from the returned interface on:
countly.Events.
Segmentation
When providing segmentation for events, the only valid data types are: "String", "Integer", "Double", and "Boolean". All other types will be ignored.
Event usage examples
Based on the example below of an event recording a purchase, here is a quick summary of the information for each usage:
- Usage 1: how many times the purchase event occurred.
- Usage 2: how many times the purchase event occurred + the total amount of those purchases.
- Usage 3: how many times the purchase event occurred + from which countries and application versions those purchases were made.
- Usage 4: how many times the purchase event occurred + the total amount, both of which are also available, segmented into countries and application versions.
- Usage 5: how many times the purchase event occurred + the total amount, both of which are also available, segmented by countries and application versions + the total duration of those events.
1. Event key and count
await countly.Events.RecordEventAsync("purchase", count: 1);
2. Event key, count, and sum
await countly.Events.RecordEventAsync(key: "purchase", count: 1, sum: 0.99);
3. Event key and count with segmentation(s)
SegmentModel segmentation= new SegmentModel();
await countly.Events.RecordEventAsync(key: "purchase", segmentation: segment, count: 1);
4. Event key, count, and sum with segmentation(s)
SegmentModel segmentation = new SegmentModel();
segmentation.Add("country", "Germany");
segmentation.Add("app_version", "1.0");
await countly.Events.RecordEventAsync(key: "purchase", segmentation: segment, count: 1, sum: 0.99);
5. Event key, count, sum, and duration with segmentation(s)
SegmentModel segmentation = new SegmentModel();
segmentation.Add("country", "Germany");
segmentation.Add("app_version", "1.0");
await countly.Events.RecordEventAsync(key: "purchase", segmentation: segment, count: 1, sum: 0.99, duration: 60);
These are only a few examples of what you can do with Events. You may go beyond those examples and use country, app_version, game_level, time_of_day, and any other segmentation of your choice that will provide you with valuable insights.
Crash reporting
The Countly SDK for Unity can collect Crash Reports, which you may examine and resolve later on the server.
Automatic crash reporting
The Unity SDK can automatically report uncaught exceptions/crashes in the application to the Countly server. To report uncaught exceptions/crashes automatically, enable enableAutomaticCrashReporting in the SDK configuration.
Accessing crash-related functionalities
In the SDK all crash-related functionalities can be browsed from the returned interface on:
countly.CrashReports.
Adding breadcrumbs
Throughout your app, you can leave crash breadcrumbs which would describe previous steps that were taken in your app before the crash. After a crash happens, they will be sent together with the crash report.
The following command adds a crash breadcrumb:
countly.CrashReports.AddBreadcrumbs("breadcrumb");
Logging handled exceptions
You might catch an exception or similar error during your app’s runtime.
You may also log these handled exceptions to monitor how and when they are happening.
Example:
try
{
throw new DivideByZeroException();
}
catch (Exception ex)
{
await countly.CrashReports.SendCrashReportAsync(ex.Message, ex.StackTrace, LogType.Exception);
}
View tracking
The Countly Unity SDK supports manual view (screen) tracking. With this feature, you can report what views a user did and for how long. Thus, whenever there is a screen switch in your app, you can report it to the Countly server by using the following method:
await countly.Views.RecordOpenViewAsync("Home Scene");
When the screen closes you can report it to the server by using the following method:
await countly.Views.RecordCloseViewAsync("Home Scene");
View actions
It is possible to report actions taken on views for heat maps or any other purpose. For that, use the following method:
await countly.Views.ReportActionAsync("Click", 300, 500, 720, 1280);
User location
While integrating this SDK into your application, you might want to track your user location. You could use this information to better know your app’s user base. There are 4 fields that can be provided:
- Country code (two-letter ISO standard).
- City name (must be set together with the country code).
- Latitude and longitude values separated by a comma, e.g. "56.42345,123.45325".
- Your user’s IP address.
string countryCode = "us";
string city = "Houston";
string latitude = "29.634933";
string longitude = "-95.220255";
string ipAddress = null;
countly.OptionalParameters.SetLocation(countryCode, city, latitude + "," + longitude, ipAddress);
Disabling location
Users might want to opt-out of location tracking. To do so, call:
countly.OptionalParameters.DisableLocation();
This action will erase the cached location data from the device and the server.
Ratings
Ratings is a customer satisfaction tool that collects direct user feedback and comments. For more details, please see the Ratings documentation.
When a user rates your application, you can report it to the Countly server using the following method:
await countly.StarRatingReport.StarRatingAsync("android", "0.1", 3);
Remote Config
Available in the Enterprise Edition, Remote Config allows you to modify how your app functions or looks by requesting key-value pairs from your Countly server. The returned values may be modified based on the user profile. For more details, please see the Remote Config documentation.
Downloading Remote Config
To download Remote Config, call countly.RemoteConfigs.Update()
. After the successful download, the SDK stores the updated config locally.
await countly.RemoteConfigs.Update();
Getting Remote Config
To access the stored config, call countly.RemoteConfigs.Configs
. It will return null
if there isn't any config stored.
Dictionary<string, object> config = countly.RemoteConfigs.Configs;
User Profiles
The Countly Unity SDK allows you to upload specific data related to a user to the Countly server. The SDK allows you to set the following predefined data for a particular user:
- Name: Full name of the user.
- Username: Username of the user.
- Email: Email address of the user.
- Organization: Organization the user is working in.
- Phone: Phone number.
- Picture Url: Web-based Url for the user’s profile.
- Gender: Gender of the user (use only single char like ‘M’ for Male and ‘F’ for Female).
- Birth year: Birth year of the user.
Apart from the above data, you can also add custom data for a user. The SDK allows you to upload user details using the methods listed below.
Setting up User Profiles
Available in Countly Enterprise, User Profiles is a tool that helps you identify users, their devices, event timelines, and application crash information.
You may send user-related information to Countly and let the Countly Dashboard show and segment this data. You may also send a notification to a group of users. For more information about User Profiles, review this documentation.
Example:
var userDetails = new CountlyUserDetailsModel( "Full Name", "username", "useremail@email.com", "Organization", "222-222-222", "http://webresizer.com/images2/bird1_after.jpg", "M", "1986",
new Dictionary<string, object> {
{ "Hair", "Black" },
{ "Race", "Asian" },
});
await countly.UserDetails.SetUserDetailsAsync(userDetails);
Setting up custom user details
The SDK gives you the flexibility to send only the custom data to Countly servers, even when you don’t want to send other user-related data. Similar to the above method, it is also an instance method and not a static method. So, you first need to create an instance of the class CountlyUserDetailsModel
. All the parameters expected in the constructor remain the same. You can leave all parameters as null and just provide the custom data segment for sending custom data to the Countly server.
Example:
var userDetails = new CountlyUserDetailsModel( new Dictionary<string, object> {
{ "Height", "5.8" },
{ "Mole", "Lower Left Cheek" }
});
await countly.UserDetails.SetCustomUserDetailsAsync(userDetails);
Modifying custom data
You may also perform different manipulations to your custom data values, such as incrementing the current value on a server or storing an array of values under the same property.
You will find the list of available manipulations below:
//set one custom properties
await countly.UserDetails.Set("test", "test");
//increment used value by 1
await countly.UserDetails.Increment("used");
//increment used value by provided value
await countly.UserDetails.IncrementBy("used", 2);
//multiply value by provided value
await countly.UserDetails.Multiply("used", 3);
//save maximal value
await countly.UserDetails.Max("highscore", 300);
//save minimal value
await countly.UserDetails.Min("best_time",60);
//set value if it does not exist
await countly.UserDetails.SetOnce("tag", "test");
//insert value to array of unique values
await countly.UserDetails.PushUnique("type", "morning");
//insert value to array which can have duplicates
await countly.UserDetails.Push("type", "morning");
//remove value from array
await countly.UserDetails.Pull("type", "morning");
//send provided values to server
await countly.UserDetails.SaveAsync()
In the end, always call await countly.UserDetails.SaveAsync();
to send them to the server.
Recording multiple update requests
Apart from updating a single property in one request, you can modify multiple (unique) properties in one single request. This way you can increment Weight and multiply Height in the same request. Similarly, you can record any number of modified requests and Save them all together in one single request instead of multiple requests.
Note that if you are going to modify multiple properties in one request, make sure your properties are unique, i.e., a property shouldn’t be modified more than once in a single request. However, if you record a property more than once, only the latest value will be posted to the server.
Example:
countly.UserDetails.Max("Weight", 90);
countly.UserDetails.SetOnce("Distance", "10KM");
countly.UserDetails.Push("Mole", new string[] { "Left Cheek", "Back", "Toe" }); ;
await countly.UserDetails.SaveAsync();
Changing Device ID
The Countly Unity SDK persists Device ID when you provide it during initialization or generates a random ID when you don’t provide it. This Device ID will be used persistently for all future requests made from a device until you change that.
The SDK allows you to change the Device ID at any point in time. You can use any of the following two methods to changing the Device ID, depending on your needs.
Changing Device ID without server merge
This method changes the Device ID and does the following other operations:
- Ends all the events that have been recorded untill now.
- Ends the current session.
- Updates Device ID and starts a new session with a new Device ID.
Example:
await countly.Device.ChangeDeviceIDAndEndCurrentSessionAsync("New Device Id");
Changing Device ID with server merge
This method changes the Device ID and merges data for both Device IDs in the Countly server.
Example:
await countly.Device.ChangeDeviceIDAndEndCurrentSessionAsync("New Device Id");
Push Notification
The Countly Unity SDK supports FCM (Firebase Cloud Messaging) for Android. By default Push Notifications are disabled. To enable them go to the Countly prefab settings and change Notification Mode in the Configuration.
Use an iOS Test Token or an Android Test Token for testing purposes and in production use a Production Token
Android
FCM credentials
The Countly server needs an FCM server key to send notifications through FCM.
To set it up, refer to Android documentation.
Integrating FCM into your app
- Download google-services.json from Firebase console.
- Create google-services.xml from google-services.json. You can use an online converter here.
- Put your file google-services.xml in /Plugins/Android/Notifications/res/values (replace if necessary).
Changing Notification Sound and Icons
In order to change the sound and icons of the notifications, replace the sound and icons in the folder Assets/Plugins/Android/Notifications/res.
Note: The Notification channel name and description can be updated throgh the strings.xml file located in the Assets\Plugins\Android\Notifications\res\values folder.
Remove FCM Dependencies
By default, FCM dependencies are part of the SDK. To remove FCM dependencies, go to the Assets\Plugins\Android folder and delete the Notifications folder.
To add them back after removing, re-import the Unity package.
iOS
Adding Scripting Define Symbols
In Unity, go to Player Settings. In the Other Settings section, add the "COUNTLY_ENABLE_IOS_PUSH" symbol in Scripting Define Symbols.
APNs Credentials
The Countly server needs the APNs Auth Key to send notifications. To get the APNs Auth Key and upload it to the County Server, refer to iOS Documentation.
Configuring the iOS app
After exporting the iOS project, open the project in Xcode, and add Push Notifications Capability.
Removing the APNs Dependencies
By default, the APNs dependencies are part of the SDK. To remove the APNs dependencies, go to the Assets\Plugins folder and delete the iOS folder. Remove the "COUNTLY_ENABLE_IOS_PUSH" symbol from Scripting Define Symbols in Player Settings.
To add them back after removing, re-import the Unity package and add back the "COUNTLY_ENABLE_IOS_PUSH" symbol.