# Unity

Our CMP is available for Unity as a Unity Package containing plugins for Android, iOS and tvOS. The package is available from the following git repository:

[AppConsent Unity package](https://gitlab.datalf.chat/customers/appconsent-unity.git)

Minimum supported version of unity is **2021.3.46f1 LTS**.

<https://unity.com/fr/releases/editor/archive>

***

## Simple execution

This example is taken directly from the sample code below.

<figure><img src="https://4229351976-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkyFlZKFaKP4MUM0zILOg%2Fuploads%2Fr7xQllxG3byHjnJy54MX%2FAppConsent_201_unity.gif?alt=media&#x26;token=0b653986-ed9a-4eae-a13a-1295c3f32bb6" alt=""><figcaption></figcaption></figure>

### Runner Sample

Here's the Unity sample runner project into which we've integrated our solution. [Sample](https://gitlab.datalf.chat/customers/appconsent-runner-sample)

### Developer Sample

Here's a sample Unity project in which we've integrated our solution, enabling you to interact directly with it from the main screen. [Sample](https://gitlab.datalf.chat/customers/appconsent-unity-sample)

## Add the SFBX AppConsent package to your Unity project

From the *window* menu, open the *Package Manager*

<figure><img src="https://4229351976-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkyFlZKFaKP4MUM0zILOg%2Fuploads%2FLEV73uhNVc8G1sfXvZ5q%2Fopen_project_manager.png?alt=media&#x26;token=7e429575-6b80-41b9-bc3a-7da2205aa48f" alt=""><figcaption></figcaption></figure>

Inside the Package Manager window, click on the *+* button *+* in the top-left corner. From the drop-down menu select *Add package from git URL*.

<figure><img src="https://4229351976-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkyFlZKFaKP4MUM0zILOg%2Fuploads%2FiDy7DaRKlj4Wc62DVg61%2Fadd_package_from_git_URL.png?alt=media&#x26;token=5d30cd40-3412-4c11-b372-cfc29a685ce7" alt=""><figcaption></figcaption></figure>

In the popup text field, enter the url to the package's git repository <https://gitlab.datalf.chat/customers/appconsent-unity.git> and click on *Add*.

<figure><img src="https://4229351976-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkyFlZKFaKP4MUM0zILOg%2Fuploads%2FKmQaycpOvzWmK9JWttvA%2Fadd_url.png?alt=media&#x26;token=7e6a8d29-92c1-47f9-ae88-593ecac6de20" alt=""><figcaption></figcaption></figure>

The SFBX AppConsent package has been added to your project.

<figure><img src="https://4229351976-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkyFlZKFaKP4MUM0zILOg%2Fuploads%2F5QNKsk0lB05pyLaIXvP4%2FSFBX_AppConsent_added.png?alt=media&#x26;token=67a5f51a-ccf8-48b8-895f-752d0644137c" alt=""><figcaption></figcaption></figure>

***

## Recommendation Android

The plugin allows you to define a success or error callback before CMP initialization, enabling you to log and/or use the CMP when it is fully initialized (asynchronous).

Here's an example of how CMP works on Android

```kotlin
using SFBX.AppConsent;
using UnityEngine;
using System.Collections;

public class AppConsentGUI : MonoBehaviour, ISDKCallbackListener, ISDKPresentNoticeListener
{
    ACNotice bridge = null;
    private bool isCmpInitialized = false;
    int centerX = Screen.width / 2;
    int buttonWidth = Screen.width / 2;
    int buttonHeight = Screen.height / 14;
    int buttonX;

    GUIStyle labelStyle = new GUIStyle();
    GUIStyle buttonStyle;

    string status = "";
    int logIndice = 0;

    void Awake()
    {
        AndroidJNIHelper.debug = true;
        // Only for Android - does not impact iOS !
        ACNotice.SetNoticeCallback(this);
        bridge = new ACNotice("18ecaea4-554a-4f74-9242-520fe62058a8");
        UpdateStatus("bridge instanciated => " + bridge);
    }

    // Start is called before the first frame update
    void Start()
    {
        labelStyle.alignment = TextAnchor.MiddleCenter;
        labelStyle.normal.textColor = Color.white;
        buttonX = centerX - ( buttonWidth / 2);
        
        bridge.InitACNotice();

        #if UNITY_IOS || UNITY_TVOS
            // On iOS, there's no need for a callback, so you can directly change the boolean's state. 
            OnReadyOnSuccess();
        #endif
    }

    // Update is called once per frame
    void Update()
    {
        centerX = Screen.width / 2;
        buttonWidth = Screen.width / 2;
        buttonHeight = Screen.height / 14;
        buttonX = centerX - ( buttonWidth / 2);
    }

    void OnGUI()
    {
        labelStyle.fontSize = 28;
        labelStyle.wordWrap = true;

        buttonStyle = new GUIStyle(GUI.skin.button);
        buttonStyle.fontSize = 28;

        GUI.Label(new Rect(buttonX, buttonHeight * 2, buttonWidth, buttonHeight), "SFBX AppConsent", labelStyle);

        if (GUI.Button(new Rect(buttonX, buttonHeight * 4, buttonWidth, buttonHeight), "Display CMP", buttonStyle))
        {
            if(isCmpInitialized == true && bridge != null){
                bridge.SetPresentNoticeListener(this);
                bool isDisplayed = bridge.ShowNotice();
                if(isDisplayed == true){
                    UpdateStatus("Notice displayed");
                }else{
                    UpdateStatus("Notice not displayed, look at your consent or RGPD country.");
                }
            }else{
                UpdateStatus("AppConsent not ready yet");
            }
        }

        if (GUI.Button(new Rect(buttonX, buttonHeight * 6, buttonWidth, buttonHeight), "Settings", buttonStyle))
        {
            if(isCmpInitialized == true && bridge != null){
                bridge.ShowSettings();
                UpdateStatus("Settings displayed");
            }else{
                UpdateStatus("AppConsent not ready yet");
            }
        }

        if (GUI.Button(new Rect(buttonX, buttonHeight * 8, buttonWidth, buttonHeight), "Check Consents", buttonStyle))
        {
            if(isCmpInitialized == true && bridge != null){
                bool consent = bridge.ConsentGiven();
                bool allConsentables = bridge.AllConsentablesAllowed();
                bool gdpr = bridge.IsSubjectToGDPR();
                bool acceptAll = bridge.UserAcceptAll();
                bool extra = bridge.ExtraVendorAllowed("TobuM9Iw");
                bool consentable = bridge.ConsentableAllowed(1,0);
                UpdateStatus("consents: " + consent + allConsentables + gdpr + acceptAll + extra + consentable);
            }else{
                UpdateStatus("AppConsent not ready yet");
            }
        }

        if (GUI.Button(new Rect(buttonX, buttonHeight * 10, buttonWidth, buttonHeight), "Reset Consents", buttonStyle))
        {
            if(isCmpInitialized == true && bridge != null){
                bridge.ClearConsents();
                UpdateStatus("Cleared consents");
            }else{
                UpdateStatus("AppConsent not ready yet");
            }
        }

        GUI.Label(new Rect(0, buttonHeight * 12, Screen.width, buttonHeight), status, labelStyle);
    }

    public void OnReadyOnSuccess()
    {   
        UpdateStatus("Appconsent onReadyOnSuccess");
        isCmpInitialized = true;
        
        Debug.Log("AppConsent is ready to be use !");
        UpdateStatus("Setting listener + trying to show notice");
        bridge.SetPresentNoticeListener(this);

        bool isDisplayed = bridge.ShowNotice();
        if(isDisplayed == true){
            UpdateStatus("Notice displayed");
        }else{
            UpdateStatus("Notice not displayed, look at your consent or RGPD country.");
        }
    }
    
    public void OnReadyOnError(AndroidJavaObject err)
    {
        isCmpInitialized = false;
        Debug.LogError("Failed to start AppConsent");
    }

    public void OnConsentGiven()
    {
        Debug.Log("The user has given his consent");
        UpdateStatus("Consent given !");
    }

    public void OnConsentGivenError(AndroidJavaObject err)
    {
        Debug.LogError("An error as occurred, please read Log.");
        UpdateStatus("An error as occurred, please read Log.");
    }

    private void UpdateStatus(string log){
        if(logIndice % 10 == 0){
            status = logIndice++ + " - " + log;
        }else{
            status = status + "\n" + logIndice++ + " - " + log;
        }
    }
}
```

## API Documentation

Detailed API documentation is available [here](https://docs.sfbx.io/unity-api-reference/index.html).

## FAQ

All our FAQs can be found in our git [README](https://gitlab.datalf.chat/customers/appconsent-unity/-/blob/master/README.md)
