LogoLogo
Metica.comLaunch app →
  • Getting Started
  • REST API Integration
  • MMP integration
  • Unity SDK
Powered by GitBook
On this page
  • Overview
  • Terminology
  • What you need
  • Installation
  • Upgrading from 1.3.1 to 1.5.0
  • How to use the Metica SDK
  • Event Dispatch (Flushing)
  • Setup
  • Available SDK Operations
  • Initialize the API
  • SDK Configuration
  • Get Offers
  • Device Info
  • Remote Configuration (Smart Configs)
  • Offer Lifecycle Events
  • Full State Update
  • Partial State Update
  • Custom Payloads
  • Custom Event Logging
  • Ads Integration
  • Initialization
  • Interstitial ads
  • Loading an Interstitial Ad
  • Showing an Interstitial Ad
  • Metica SDK vs AppLovin Interstitial API
  • API Calls
  • Callbacks
  • Code Samples
  • Privacy Manifest

Was this helpful?

Unity SDK

PreviousMMP integration

Last updated 14 days ago

Was this helpful?


This document provides a quick summary on how to use the Metica Unity SDK.

Overview

The Metica Unity SDK offers a straightforward interface for interacting with the Metica backend API from your Unity game directly. The SDK provides simplified methods to fetch offers and smart configs (abbreviated as configs), and to log user actions within your app or game as events. The Metica Unity SDK takes care of networking nuance, caching and much more so you don't have to.

Terminology

  • Application Your application or game that uses the Metica services.

  • User A user or player of the application. Player and user are used interchangeably.

  • Event An event refers to a user's action within the context of the application. For example, clicking a button, logging in, clicking an ad, etc. The properties (or attributes) associated with these events vary based on the type of the event; e.g., the property totalAmount must be set when logging an in-app offer purchase event.

  • User Properties Sometimes (and formerly) called User Attributes, user properties consist of general information about the user that best characterises them in your application. For example you could define your user properties to include game progression, demographics, user preferences, player's level, etc.

What you need

To use the Metica Unity SDK you need:

  • An API key, obtainable in the Metica platform

  • An appId, obtainable in the Metica platform.

Installation

In Unity, open the Package Manager (Window > Package Manager) and click on the '+' button in the top left corner. Select "Add package from git URL..." and enter the following:

https://github.com/meticalabs/metica-unity-sdk.git?path=SDK

Upgrading from 1.3.1 to 1.5.0

The MeticaAPI class was the main surface to use the SDK. We preserved it but since we renamed some types, you may need to add, at the start of the file, one or both of the following lines where OffersByPlacement and/or MeticaLogger are not found.

using MeticaLogger = Log;
using OffersByPlacement = Metica.SDK.OfferResult;

How to use the Metica SDK

The recommended way to use the sdk is through MeticaSdk which offers async/await methods alongside coroutine ones.

For backwards compatibility the old deprecated mechanism is still available which has only the coroutine approach: MeticaAPI

You can retrieve an instance of IMeticaSdk with

private IMeticaSdk _sdk = MeticaSdk.SDK;

If you do so, you can now take advantage of the asynchronous calls. Example:

configResult = await _sdk.GetConfigsAsync(new List<string> { "dynamic_difficulty" });

One of the main advantages is that you now have a return type rather than having to pass a callback method.

Event Dispatch (Flushing)

When you log an event (both with static calling or using async), it isn't guaranteed to be sent immediately as events are sent in bulks.

If you need to make sure events are immediately sent to the ingestion endpoint, you can use the RequestDispatchEvents call but don't overuse it as the default behaviour helps aggregating events for lower network load.

Setup

No code is needed to initialize the Metica Unity SDK as, with recent changes, the process has been reduced to the following steps in Unity.

  1. In Unity's Hierarchy View, right click (on an empty area) and select Metica > Add SDK. This will add a prefab with the MeticaUnitySdk component attached (if not already in scene). Alternatively you can manually drag and drop the prefab from Packages/Metica Unity Sdk/Runtime/Unity/Prefabs/.

  2. Select the prefab and click the Create Configuration button to create and save it in the folder you select.*

  3. If needed, add the file to the MeticaSdk prefab. When you use the Create Configuration button the configuration should be automatically linked.

*: Alternatively, create a configuration asset by right-clicking a folder in the Project View and selecting Create > Metica > SDK > New SDK Configuration. This can also be found in the main menu under Assets > Create > Metica but it will create the asset in the Assets' root.

Available SDK Operations

Initialize the API

If you upgraded to the new SDK and your code is still calling the Initialise method to prepare the MeticaAPI, it's not a problem but you can remove it. If you leave it, a harmless warning will appear.

With versions of the SDK <= 1.3.1 the initialization is done as follows:

⚠️: This method is obsolete. Please prefer the next call using SdkConfig.

MeticaAPI.Initialise("userId", "appId", "apiKey", result => { 
    if (result.Result) { Debug.Log("Metica API Initialized"); } 
    else { Debug.Log("Failed to Initialize Metica API: " + result.Error); } 
});

You can pass an instance of SdkConfig, if you want to have greater control over the SDK's operations.

var config = SdkConfig.Default();
config.logLevel = LogLevel.Off;
config.networkTimeout = 5;
MeticaAPI.Initialise("userId", "appId", "apiKey", config, result => { 
    ... 
});

SDK Configuration

The SDK configuration exposes the following parameters:

Property
Description

apiKey

Your API key

appId

The application identifier accessible from Metica's dashboard.

initialUserId

A string that identifies a user. This can change during the lifetime of your app/game so, for example and depending on your needs, this could be a temporary id like "guest" that later becomes a specific userId, or it can be the current user's id if it's already identified.

Base Endpoint

Base metica endpoint : https://api-gateway.prod-eu.metica.com

Events Log Dispatch Cadence

The cadence, in seconds, that triggers an events dispatch.

displayLogFlushCadence

The number of stored events above which they are dispecthed (actually sent to Metica). Events in fact don't get always sent immediately, they accumulate and get sent in bulks.

Events Log Dispatch Cadence

The cadence, in seconds, by which the logged events will be sent to the ingestion service.

Events Log Dispatch Max Queue Size

The maximum number of pending logged events before they are sent to the ingestion service. When this value is reached, oldest accumulated events will be dropped to accommodate most recent ones.

Http Cache TTL Seconds

The time-to-live, in seconds, for the http-level cache.

Http Request Timeout

The network timeout, in seconds, for the calls to any Metica endpoint.

Log Level

The level of the SDK's logs. Do not confuse this with the meaning Log in the context of event logging. The valid values are provided by the enumeration Metica.SDK.LogLevel and determine the verbosity of the logs with Info being the most verbose and Debug being the least verbose. Offsuppresses all logging.

Get Offers

Asynchronously fetches offers for specified (or all) placements from the Metica API. The result is delivered through a callback and consists of a dictionary of placements with their respective offers.

A dictionary of user attributes can be passed to the method to personalize the offers. If not, then the last known user attributes are used.

Signature

public static void GetOffers(String[] placements, MeticaSdkDelegate<OfferResult> responseCallback, Dictionary<string, object> userProperties = null, DeviceInfo deviceInfo = null)

Example

MeticaAPI.GetOffers(new string[] { "placementId1", "placementId2" }, result => { 
        if (result.Error == null) { 
            foreach (var offer in result.Result.placements["placementId1"]) 
            { 
                Debug.Log(offer); 
            } 
        } else 
        { 
            Debug.Log("Failed to get offers: " + result.Error); 
        } 
    },
    userProperties: {
        { "someAttribute", true },
        { "another", "someValue" }
    }, 
    deviceInfo: new DeviceInfo()
        {
            appVersion = "1.0.0",
            timezone = "UTC",
            locale = "en_US",
            store = "AppStore"
        });

Device Info

The DeviceInfo stores information regarding the host device, and it can differ across different devices of the same user.

Note that leaving this variable to null is perfectly fine as it will trigger a device detector that is internal to the SDK

An overview of the role of each DeviceInfo property:

Property
Type
Description
Example

store

string

Identifies the app store related to the in-game offers. Possible values: - GooglePlayStore, the Google store - AppStore, the Apple store

GooglePlayStore

timezone

string

+01:00

appVersion

string

0.1.5

locale

string

en-US

Remote Configuration (Smart Configs)

The GetConfig method can be used to retrieve the Smart Configs.

Similar to the GetOffers method, the operation is performed asynchronously and the result is delivered through a callback. Because the result is specific to each application, the SDK represents it in a generic manner, through an Dictionary<string, object> instance. Each entry in the dictionary represents a configuration key and its value. The latter is expected to be valid json.

Also, again similar to the GetOffers method, the operation can be passed a dictionary of user properties and the device details, as a DeviceInfo instance, in order to personalise the returned configuration. The personalisation happens on the server side, based on the configured variations and experimentation setup.

Signature

public static void GetConfigAsConfigResult(MeticaSdkDelegate<ConfigResult> responseCallback, List<string> configKeys = null, Dictionary<string, object> userProperties = null, DeviceInfo deviceInfo = null)

Note that the name includes AsConfigResult. For retro-compatibility we had to append this to the method name but in the future this signature, using ConfigResult as return type, will be the standard. The GetConfig method, using Dictionary<string, object> as return type, will be marked obsolete in the next versions.

Example

_sdk.GetConfig(
    configKeys: new string[] { "key1", "key2" },
    responseCallback: result => { 
        if (result.Error == null) 
        {             
            Debug.Log(result.Result.Configs["key1"]);             
        } else 
        { 
            Debug.Log("Failed to get offers: " + result.Error); 
        } 
    },
    userProperties: {
        { "someAttribute", true },
        { "another", "someValue" }
    }, 
    deviceInfo: new DeviceInfo()
        {
            appVersion = "1.0.0",
            timezone = "UTC",
            locale = "en_US",
            store = "AppStore"
        });

If the configKeys argument is null or empty, then all the configured keys will be returned.

Note that the server side response for this call is going to be cached according to the cache control directives returned by the server.

Offer Lifecycle Events

Logs offer related events like offer display, offer purchase, and offer interaction.

Examples:

_sdk.LogOfferDisplay("<offerId>", "<placementId>");
_sdk.LogOfferDisplayWithProductId("<productId>");
_sdk.LogOfferPurchase("<offerId>", "<placementId>", 10.0, "USD");
_sdk.LogOfferPurchaseWithProductId("<productId>", 10.0, "USD");
_sdk.LogOfferInteraction("<offerId>", "<placementId>", "click");
_sdk.LogOfferInteractionWithProductId("<productId>", "click");

Full State Update

LogFullStateUpdate sends a complete snapshot of the user's state to the server, replacing any previously stored data. Please note that this method fully resets the user's state on the server and expects all relevant state information to be included in the request. Any user attributes that are currently stored in the server with the given userId but are not sent with this update, will be erased.

Dictionary<string, object> userAttributes = new Dictionary<string, object> { { "level", 25 }, { "favoriteItem", "shield" } };
MeticaAPI.LogFullStateUpdate(userAttributes); 

Partial State Update

LogPartialStateUpdate sends a partial update of the user's state to the server, modifying or adding only the provided fields while preserving those that are currently stored on the server. This method cannot erase existing fields (like LogFullStateUpdate does); it can only overwrite values or introduce new ones.

Custom Payloads

All events, except fullStateUpdate, partialStateUpdate and CustomEvent, support a custom payload that can include any information. It's passed as a Dictionary<string, object> to the logging methods. To avoid confusion with other fields, it is recommended to pass the parameter by name, i.g. LogInstall(customPayload: playerExtraParams) rather than just LogInstall(playerExtraParams).

Example

Dictionary<string, object> myCustomPayload {
{ "set", "Intense Stare Magic Mastery" },
{ "cosmetic", "flamingo shades" },
};
LogOfferInteraction(someOfferId, somePlacementId, "selected", myCustomPayload);
LogOfferPurchase(someOfferId, somePlacementId, 2.49, "GBP", customPayload: myCustomPayload);

Custom Event Logging

LogCustomEvent logs custom application events. The only required field in this dictionary is eventType which is used by Metica to classify the different types of events your application is sending.

Dictionary<string, object> customUserEvent = new Dictionary<string, object> { { "eventType", "completed_level" }, { "eventDetails", "level 5" } };
_sdk.LogCustomEvent(userEvent);
// this will avoid the extra allocation but will mutate the passed userEvent
_sdk.LogCustomEvent(customEventType, true);

Ads Integration

This section explains how to integrate Metica's interstitial ads into your Unity project. Metica's streamlined API simplifies ad integration by automatically handling ad unit IDs and optimizing ad selection.

Initialization

MeticaAds.Initialize()

Interstitial ads

Interstitial ads are full-screen or full-page ads that temporarily cover an app’s interface. They’re typically shown at natural pauses or transition points, such as after completing a level in a game or when navigating between major views.

The following sections show you how to load and then show an interstitial ad.

Loading an Interstitial Ad

The following code shows you how to attach listeners and load the first interstitial ad:

private void InitializeInterstitialAds() {
    // Attach callbacks
    MeticaAdsCallbacks.Interstitial.OnAdLoadSuccess += OnInterstitialLoadedEvent;
    MeticaAdsCallbacks.Interstitial.OnAdLoadFailed += OnInterstitialFailedEvent;
    MeticaAdsCallbacks.Interstitial.OnAdShowSuccess += OnInterstitialDisplayedEvent;
    MeticaAdsCallbacks.Interstitial.OnAdShowFailed += InterstitialFailedToDisplayEvent;
    MeticaAdsCallbacks.Interstitial.OnAdClicked += OnInterstitialClickedEvent;
    MeticaAdsCallbacks.Interstitial.OnAdHidden += OnInterstitialDismissedEvent;
    // Load the first interstitial
    LoadInterstitial();
}
void LoadInterstitial() {
    var userId = "foobar";
    MeticaAds.LoadInterstitialAsync(userId);
}
private void OnInterstitialLoadedEvent(string adUnitId) {
    // Interstitial ad is ready to be shown. MeticaAds.IsInterstitialReady() will now return 'true'
}
private void OnInterstitialFailedEvent(string adUnitId, string error) {
    // Interstitial ad failed to load. We recommend retrying with exponentially higher delay.
}
private void OnInterstitialDisplayedEvent(string adUnitId) {
    Debug.Log($"Interstitial shown {adUnitId}");
}
private void InterstitialFailedToDisplayEvent(string adUnitId, string error) {
    // Interstitial ad failed to display. We recommend loading the next ad
    Debug.Log("Interstitial failed to display: " + error);
    LoadInterstitial();
}
private void OnInterstitialClickedEvent(string adUnitId) {
    Debug.Log($"Interstitial clicked {adUnitId}");
}
private void OnInterstitialDismissedEvent(string adUnitId) {
    // Interstitial ad is hidden. Pre-load the next ad
    Debug.Log("Interstitial dismissed");
    LoadInterstitial();
}

Showing an Interstitial Ad

To show an interstitial ad, call ShowInterstitial():

void ShowInterstitial()
{
   if (MeticaAds.IsInterstitialReady())
   {
       MeticaAds.ShowInterstitialAsync();
   }
}

Metica SDK vs AppLovin Interstitial API

API Calls

Metica's API in contrast to AppLovin does not require an adUnitId to be passed. The reason is that Metica's AI technology automatically selects and manages the optimal ad unit IDs behind the scenes, eliminating the need for developers to manually specify these IDs in each function call and simplifying integration.

Metica Ads API

MeticaAds.LoadInterstitialAsync(userId);        
MeticaAds.IsInterstitialReady();                
MeticaAds.ShowInterstitialAsync();

Max SDK API

MaxSdk.LoadInterstitial(InterstitialAdUnitId);  
MaxSdk.IsInterstitialReady(InterstitialAdUnitId); 
MaxSdk.ShowInterstitial(InterstitialAdUnitId);

Callbacks

Metica Ad Callbacks

MeticaAdsCallbacks.Interstitial.OnAdLoadSuccess
MeticaAdsCallbacks.Interstitial.OnAdLoadFailed
MeticaAdsCallbacks.Interstitial.OnAdShowSuccess
MeticaAdsCallbacks.Interstitial.OnAdShowFailed
MeticaAdsCallbacks.Interstitial.OnAdClicked
MeticaAdsCallbacks.Interstitial.OnAdHidden

Max Ad Callback

MaxSdkCallbacks.Interstitial.OnAdLoadedEvent
MaxSdkCallbacks.Interstitial.OnAdLoadFailedEvent
MaxSdkCallbacks.Interstitial.OnAdDisplayedEvent
MaxSdkCallbacks.Interstitial.OnAdDisplayFailedEvent
MaxSdkCallbacks.Interstitial.OnAdClickedEvent
MaxSdkCallbacks.Interstitial.OnAdHiddenEvent

Code Samples

The Metica Unity SDK package includes examples that can be easily imported into your Assets by selecting the package in the Package Manager and clicking the Import button next to one of the examples.

Currently available examples:

  • MeticaExample01 shows how to use the SDK via MeticaAPI(deprecated). This uses the static calls code style.

  • MeticaExample02 shows how to use the SDK by retrieving the instance and using asynchronous code style.

Privacy Manifest

Select the configuration file and fill the fields (see )

Also, a DeviceInfo (see ) object can be passed to the method to provide device information. If not, then the device information is automatically collected.

Device timezone expressed with

The game/app version, in format

Locale expressed as a combination of language (ISO 639) and country (ISO 3166) .

For more details regarding the DeviceInfo properties, check the section on

Note: The final event that is submitted to the Metica backend is enriched with additional information that's gathered by the SDK. See for further information. In a scenario where you weren't using Metica SDK you'd have to code your game/app so these fields are always included.

This guide assumes that the AppLovin SDK has already been configured. Otherwise please follow guide.

For iOS, iPadOS, tvOS and watchOS apps, we provide a at that describes the data collected by the Metica SDK.

Base Fields
this
privacy manifest
Assets/Plugins/PrivacyInfo.xcprivacy
SDK Configuration
Device Info
Get Offers
IANA tz identifier format
SemVer
JDK 8 standard reference