using UnityEngine; using System.Collections; using System.Collections.Generic; using System; using GameAnalyticsSDK.Events; using GameAnalyticsSDK.Setup; using GameAnalyticsSDK.Wrapper; using GameAnalyticsSDK.State; using System.Runtime.InteropServices; #if UNITY_EDITOR using UnityEditor; using System.IO; #endif #if UNITY_IOS using GameAnalyticsSDK.iOS; #endif namespace GameAnalyticsSDK { [RequireComponent(typeof(GA_SpecialEvents))] [ExecuteInEditMode] public partial class GameAnalytics : MonoBehaviour { #region public values private static GameAnalyticsSDK.Setup.Settings _settings; public static GameAnalyticsSDK.Setup.Settings SettingsGA { get { if(_settings == null) { InitAPI(); } return _settings; } private set{ _settings = value; } } private static GameAnalytics _instance; #endregion private static bool _hasInitializeBeenCalled; #region unity derived methods #if UNITY_EDITOR void OnEnable() { EditorApplication.hierarchyWindowItemOnGUI += GameAnalytics.HierarchyWindowCallback; if(Application.isPlaying) _instance = this; } void OnDisable() { EditorApplication.hierarchyWindowItemOnGUI -= GameAnalytics.HierarchyWindowCallback; } #else void OnEnable() { Application.logMessageReceived += GA_Debug.HandleLog; } void OnDisable() { Application.logMessageReceived -= GA_Debug.HandleLog; } #endif public void Awake() { if (!Application.isPlaying) { return; } if(_instance != null) { // only one system tracker allowed per scene Debug.LogWarning("Destroying duplicate GameAnalytics object - only one is allowed per scene!"); Destroy(gameObject); return; } _instance = this; DontDestroyOnLoad(gameObject); } void OnDestroy() { if(!Application.isPlaying) return; if(_instance == this) _instance = null; } #if (!UNITY_EDITOR && UNITY_WSA) [DllImport("GameAnalytics.UWP.dll")] private static extern void onQuit(); #endif void OnApplicationQuit() { #if (!UNITY_EDITOR && !UNITY_IOS && !UNITY_ANDROID && !UNITY_TVOS && !UNITY_WEBGL && !UNITY_TIZEN && !UNITY_SWITCH && !UNITY_PS4 && !UNITY_XBOXONE) #if (UNITY_WSA) onQuit(); #else GameAnalyticsSDK.Net.GameAnalytics.OnQuit(); # endif #if UNITY_STANDALONE System.Threading.Thread.Sleep(1500); #endif #endif } #endregion private static void InitAPI() { try { _settings = (GameAnalyticsSDK.Setup.Settings)Resources.Load("GameAnalytics/Settings", typeof(GameAnalyticsSDK.Setup.Settings)); GameAnalyticsSDK.State.GAState.Init(); #if UNITY_EDITOR if(_settings == null) { //If the settings asset doesn't exist, then create it. We require a resources folder if(!Directory.Exists(Application.dataPath + "/Resources")) { Directory.CreateDirectory(Application.dataPath + "/Resources"); } if(!Directory.Exists(Application.dataPath + "/Resources/GameAnalytics")) { Directory.CreateDirectory(Application.dataPath + "/Resources/GameAnalytics"); Debug.LogWarning("GameAnalytics: Resources/GameAnalytics folder is required to store settings. it was created "); } const string path = "Assets/Resources/GameAnalytics/Settings.asset"; if(File.Exists(path)) { AssetDatabase.DeleteAsset(path); AssetDatabase.Refresh(); } var asset = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(asset, path); AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); Debug.LogWarning("GameAnalytics: Settings file didn't exist and was created"); Selection.activeObject = asset; //save reference _settings = asset; } #endif } catch(System.Exception e) { Debug.Log("Error getting Settings in InitAPI: " + e.Message); } } private static void InternalInitialize() { if(!Application.isPlaying) return; // no need to setup anything else if we are in the editor and not playing if(SettingsGA.InfoLogBuild) { GA_Setup.SetInfoLog(true); } if(SettingsGA.VerboseLogBuild) { GA_Setup.SetVerboseLog(true); } int platformIndex = GetPlatformIndex(); GA_Wrapper.SetUnitySdkVersion("unity " + GameAnalyticsSDK.Setup.Settings.VERSION); GA_Wrapper.SetUnityEngineVersion("unity " + GetUnityVersion()); if(platformIndex >= 0) { if (GameAnalytics.SettingsGA.UsePlayerSettingsBuildNumber) { for (int i = 0; i < GameAnalytics.SettingsGA.Platforms.Count; ++i) { if (GameAnalytics.SettingsGA.Platforms [i] == RuntimePlatform.Android || GameAnalytics.SettingsGA.Platforms [i] == RuntimePlatform.IPhonePlayer) { GameAnalytics.SettingsGA.Build [i] = Application.version; } } if (GameAnalytics.SettingsGA.Platforms [platformIndex] == RuntimePlatform.Android || GameAnalytics.SettingsGA.Platforms [platformIndex] == RuntimePlatform.IPhonePlayer) { GA_Wrapper.SetAutoDetectAppVersion(true); } else { GA_Wrapper.SetBuild (SettingsGA.Build [platformIndex]); } } else { GA_Wrapper.SetBuild (SettingsGA.Build [platformIndex]); } } if(SettingsGA.CustomDimensions01.Count > 0) { GA_Setup.SetAvailableCustomDimensions01(SettingsGA.CustomDimensions01); } if(SettingsGA.CustomDimensions02.Count > 0) { GA_Setup.SetAvailableCustomDimensions02(SettingsGA.CustomDimensions02); } if(SettingsGA.CustomDimensions03.Count > 0) { GA_Setup.SetAvailableCustomDimensions03(SettingsGA.CustomDimensions03); } if(SettingsGA.ResourceItemTypes.Count > 0) { GA_Setup.SetAvailableResourceItemTypes(SettingsGA.ResourceItemTypes); } if(SettingsGA.ResourceCurrencies.Count > 0) { GA_Setup.SetAvailableResourceCurrencies(SettingsGA.ResourceCurrencies); } if(SettingsGA.UseManualSessionHandling) { SetEnabledManualSessionHandling(true); } } public static void Initialize () { InternalInitialize(); int platformIndex = GetPlatformIndex(); if(platformIndex >= 0) { GA_Wrapper.Initialize (SettingsGA.GetGameKey (platformIndex), SettingsGA.GetSecretKey (platformIndex)); GameAnalytics._hasInitializeBeenCalled = true; } else { GameAnalytics._hasInitializeBeenCalled = true; Debug.LogWarning("GameAnalytics: Unsupported platform (events will not be sent in editor; or missing platform in settings): " + Application.platform); } } /// /// Track any real money transaction in-game. /// /// Currency code in ISO 4217 format. (e.g. USD). /// Amount in cents (int). (e.g. 99). /// Item Type bought. (e.g. Gold Pack). /// Item bought. (e.g. 1000 gold). /// Cart type. public static void NewBusinessEvent(string currency, int amount, string itemType, string itemId, string cartType) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Business.NewEvent(currency, amount, itemType, itemId, cartType, null, false); } /// /// Track any real money transaction in-game. /// /// Currency code in ISO 4217 format. (e.g. USD). /// Amount in cents (int). (e.g. 99). /// Item Type bought. (e.g. Gold Pack). /// Item bought. (e.g. 1000 gold). /// Cart type. /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewBusinessEvent(string currency, int amount, string itemType, string itemId, string cartType, IDictionary customFields, bool mergeFields=false) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Business.NewEvent(currency, amount, itemType, itemId, cartType, customFields, mergeFields); } #if UNITY_IOS || UNITY_TVOS /// /// Track any real money transaction in-game (iOS version). /// /// Currency code in ISO 4217 format. (e.g. USD). /// Amount in cents (int). (e.g. 99). /// Item Type bought. (e.g. Gold Pack). /// Item bought. (e.g. 1000 gold). /// Cart type. /// Transaction receipt string. public static void NewBusinessEventIOS(string currency, int amount, string itemType, string itemId, string cartType, string receipt) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Business.NewEvent(currency, amount, itemType, itemId, cartType, receipt, false, null, false); } /// /// Track any real money transaction in-game (iOS version). /// /// Currency code in ISO 4217 format. (e.g. USD). /// Amount in cents (int). (e.g. 99). /// Item Type bought. (e.g. Gold Pack). /// Item bought. (e.g. 1000 gold). /// Cart type. /// Transaction receipt string. /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewBusinessEventIOS(string currency, int amount, string itemType, string itemId, string cartType, string receipt, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Business.NewEvent(currency, amount, itemType, itemId, cartType, receipt, false, customFields, mergeFields); } /// /// Track any real money transaction in-game (iOS version). Additionally fetch and attach the in-app purchase receipt. /// /// Currency code in ISO 4217 format. (e.g. USD). /// Amount in cents (int). (e.g. 99). /// Item Type bought. (e.g. Gold Pack). /// Item bought. (e.g. 1000 gold). /// Cart type. public static void NewBusinessEventIOSAutoFetchReceipt(string currency, int amount, string itemType, string itemId, string cartType) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Business.NewEvent(currency, amount, itemType, itemId, cartType, null, true, null, false); } /// /// Track any real money transaction in-game (iOS version). Additionally fetch and attach the in-app purchase receipt. /// /// Currency code in ISO 4217 format. (e.g. USD). /// Amount in cents (int). (e.g. 99). /// Item Type bought. (e.g. Gold Pack). /// Item bought. (e.g. 1000 gold). /// Cart type. /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewBusinessEventIOSAutoFetchReceipt(string currency, int amount, string itemType, string itemId, string cartType, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Business.NewEvent(currency, amount, itemType, itemId, cartType, null, true, customFields, mergeFields); } #elif UNITY_ANDROID /// /// Track any real money transaction in-game (Google Play version). /// /// Currency code in ISO 4217 format. (e.g. USD). /// Amount in cents (int). (e.g. 99). /// Item Type bought. (e.g. Gold Pack). /// Item bought. (e.g. 1000 gold). /// Cart type. /// Transaction receipt string. /// Signature of transaction. public static void NewBusinessEventGooglePlay(string currency, int amount, string itemType, string itemId, string cartType, string receipt, string signature) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Business.NewEventGooglePlay(currency, amount, itemType, itemId, cartType, receipt, signature, null, false); } /// /// Track any real money transaction in-game (Google Play version). /// /// Currency code in ISO 4217 format. (e.g. USD). /// Amount in cents (int). (e.g. 99). /// Item Type bought. (e.g. Gold Pack). /// Item bought. (e.g. 1000 gold). /// Cart type. /// Transaction receipt string. /// Signature of transaction. /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewBusinessEventGooglePlay(string currency, int amount, string itemType, string itemId, string cartType, string receipt, string signature, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Business.NewEventGooglePlay(currency, amount, itemType, itemId, cartType, receipt, signature, customFields, mergeFields); } #endif /// /// Track any type of design event that you want to measure i.e. GUI elements or tutorial steps. Custom dimensions are not supported. /// /// String can consist of 1 to 5 segments. Segments are seperated by ':' and segments can have a max length of 16. (e.g. segment1:anotherSegment:gold). public static void NewDesignEvent(string eventName) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Design.NewEvent(eventName, null, false); } /// /// Track any type of design event that you want to measure i.e. GUI elements or tutorial steps. Custom dimensions are not supported. /// /// String can consist of 1 to 5 segments. Segments are seperated by ':' and segments can have a max length of 16. (e.g. segment1:anotherSegment:gold). /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewDesignEvent(string eventName, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Design.NewEvent(eventName, customFields, mergeFields); } /// /// Track any type of design event that you want to measure i.e. GUI elements or tutorial steps. Custom dimensions are not supported. /// /// String can consist of 1 to 5 segments. Segments are seperated by ':' and segments can have a max length of 16. (e.g. segment1:anotherSegment:gold). /// Number value of event. public static void NewDesignEvent(string eventName, float eventValue) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Design.NewEvent(eventName, eventValue, null, false); } /// /// Track any type of design event that you want to measure i.e. GUI elements or tutorial steps. Custom dimensions are not supported. /// /// String can consist of 1 to 5 segments. Segments are seperated by ':' and segments can have a max length of 16. (e.g. segment1:anotherSegment:gold). /// Number value of event. /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewDesignEvent(string eventName, float eventValue, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Design.NewEvent(eventName, eventValue, customFields, mergeFields); } /// /// Measure player progression in the game. It follows a 3 hierarchy structure (world, level and phase) to indicate a player's path or place. /// /// Status of added progression. /// 1st progression (e.g. world01). public static void NewProgressionEvent(GAProgressionStatus progressionStatus, string progression01) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Progression.NewEvent(progressionStatus, progression01, null, false); } /// /// Measure player progression in the game. It follows a 3 hierarchy structure (world, level and phase) to indicate a player's path or place. /// /// Status of added progression. /// 1st progression (e.g. world01). /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewProgressionEvent(GAProgressionStatus progressionStatus, string progression01, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Progression.NewEvent(progressionStatus, progression01, customFields, mergeFields); } /// /// Measure player progression in the game. It follows a 3 hierarchy structure (world, level and phase) to indicate a player's path or place. /// /// Status of added progression. /// 1st progression (e.g. world01). /// 2nd progression (e.g. level01). public static void NewProgressionEvent(GAProgressionStatus progressionStatus, string progression01, string progression02) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Progression.NewEvent(progressionStatus, progression01, progression02, null, false); } /// /// Measure player progression in the game. It follows a 3 hierarchy structure (world, level and phase) to indicate a player's path or place. /// /// Status of added progression. /// 1st progression (e.g. world01). /// 2nd progression (e.g. level01). /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewProgressionEvent(GAProgressionStatus progressionStatus, string progression01, string progression02, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Progression.NewEvent(progressionStatus, progression01, progression02, customFields, mergeFields); } /// /// Measure player progression in the game. It follows a 3 hierarchy structure (world, level and phase) to indicate a player's path or place. /// /// Status of added progression. /// 1st progression (e.g. world01). /// 2nd progression (e.g. level01). /// 3rd progression (e.g. phase01). public static void NewProgressionEvent(GAProgressionStatus progressionStatus, string progression01, string progression02, string progression03) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Progression.NewEvent(progressionStatus, progression01, progression02, progression03, null, false); } /// /// Measure player progression in the game. It follows a 3 hierarchy structure (world, level and phase) to indicate a player's path or place. /// /// Status of added progression. /// 1st progression (e.g. world01). /// 2nd progression (e.g. level01). /// 3rd progression (e.g. phase01). /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewProgressionEvent(GAProgressionStatus progressionStatus, string progression01, string progression02, string progression03, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Progression.NewEvent(progressionStatus, progression01, progression02, progression03, customFields, mergeFields); } /// /// Measure player progression in the game. It follows a 3 hierarchy structure (world, level and phase) to indicate a player's path or place. /// /// Status of added progression. /// 1st progression (e.g. world01). /// The player's score. public static void NewProgressionEvent(GAProgressionStatus progressionStatus, string progression01, int score) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Progression.NewEvent(progressionStatus, progression01, score, null, false); } /// /// Measure player progression in the game. It follows a 3 hierarchy structure (world, level and phase) to indicate a player's path or place. /// /// Status of added progression. /// 1st progression (e.g. world01). /// The player's score. /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewProgressionEvent(GAProgressionStatus progressionStatus, string progression01, int score, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Progression.NewEvent(progressionStatus, progression01, score, customFields, mergeFields); } /// /// Measure player progression in the game. It follows a 3 hierarchy structure (world, level and phase) to indicate a player's path or place. /// /// Status of added progression. /// 1st progression (e.g. world01). /// 2nd progression (e.g. level01). /// /// The player's score. public static void NewProgressionEvent(GAProgressionStatus progressionStatus, string progression01, string progression02, int score) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Progression.NewEvent(progressionStatus, progression01, progression02, score, null, false); } /// /// Measure player progression in the game. It follows a 3 hierarchy structure (world, level and phase) to indicate a player's path or place. /// /// Status of added progression. /// 1st progression (e.g. world01). /// 2nd progression (e.g. level01). /// The player's score. /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewProgressionEvent(GAProgressionStatus progressionStatus, string progression01, string progression02, int score, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Progression.NewEvent(progressionStatus, progression01, progression02, score, customFields, mergeFields); } /// /// Measure player progression in the game. It follows a 3 hierarchy structure (world, level and phase) to indicate a player's path or place. /// /// Status of added progression. /// 1st progression (e.g. world01). /// 2nd progression (e.g. level01). /// 3rd progression (e.g. phase01). /// The player's score. public static void NewProgressionEvent(GAProgressionStatus progressionStatus, string progression01, string progression02, string progression03, int score) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Progression.NewEvent(progressionStatus, progression01, progression02, progression03, score, null, false); } /// /// Measure player progression in the game. It follows a 3 hierarchy structure (world, level and phase) to indicate a player's path or place. /// /// Status of added progression. /// 1st progression (e.g. world01). /// 2nd progression (e.g. level01). /// 3rd progression (e.g. phase01). /// The player's score. /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewProgressionEvent(GAProgressionStatus progressionStatus, string progression01, string progression02, string progression03, int score, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Progression.NewEvent(progressionStatus, progression01, progression02, progression03, score, customFields, mergeFields); } /// /// Analyze your in-game economy (virtual currencies). You will be able to see the flow (sink/source) for each virtual currency. /// /// Add or substract resource. /// One of the available currencies set in Settings (Setup tab). /// Amount sourced or sinked. /// One of the available currencies set in Settings (Setup tab). /// Item id (string max length=16). public static void NewResourceEvent(GAResourceFlowType flowType, string currency, float amount, string itemType, string itemId) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Resource.NewEvent(flowType, currency, amount, itemType, itemId, null, false); } /// /// Analyze your in-game economy (virtual currencies). You will be able to see the flow (sink/source) for each virtual currency. /// /// Add or substract resource. /// One of the available currencies set in Settings (Setup tab). /// Amount sourced or sinked. /// One of the available currencies set in Settings (Setup tab). /// Item id (string max length=16). /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewResourceEvent(GAResourceFlowType flowType, string currency, float amount, string itemType, string itemId, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Resource.NewEvent(flowType, currency, amount, itemType, itemId, customFields, mergeFields); } /// /// Set up custom error events in the game. You can group the events by severity level and attach a message. /// /// Severity of error. /// Error message (Optional, can be nil). public static void NewErrorEvent(GAErrorSeverity severity, string message) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Error.NewEvent(severity, message, null, false); } /// /// Set up custom error events in the game. You can group the events by severity level and attach a message. /// /// Severity of error. /// Error message (Optional, can be nil). /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewErrorEvent(GAErrorSeverity severity, string message, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Error.NewEvent(severity, message, customFields, mergeFields); } /// /// Track fill-rate of you ads. /// /// Action of ad (for example loaded, show). /// Type of ad (for video, interstitial). /// Name of ad SDK. /// Placement of ad or identifier of the ad in the app /// Duration of ad video public static void NewAdEvent(GAAdAction adAction, GAAdType adType, string adSdkName, string adPlacement, long duration) { if(!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Ads.NewEvent(adAction, adType, adSdkName, adPlacement, duration, null, false); } /// /// Track fill-rate of you ads. /// /// Action of ad (for example loaded, show). /// Type of ad (for video, interstitial). /// Name of ad SDK. /// Placement of ad or identifier of the ad in the app /// Duration of ad video /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewAdEvent(GAAdAction adAction, GAAdType adType, string adSdkName, string adPlacement, long duration, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Ads.NewEvent(adAction, adType, adSdkName, adPlacement, duration, customFields, mergeFields); } /// /// Track fill-rate of you ads. /// /// Action of ad (for example loaded, show). /// Type of ad (for video, interstitial). /// Name of ad SDK. /// Placement of ad or identifier of the ad in the app /// Error reason for no ad available public static void NewAdEvent(GAAdAction adAction, GAAdType adType, string adSdkName, string adPlacement, GAAdError noAdReason) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Ads.NewEvent(adAction, adType, adSdkName, adPlacement, noAdReason, null, false); } /// /// Track fill-rate of you ads. /// /// Action of ad (for example loaded, show). /// Type of ad (for video, interstitial). /// Name of ad SDK. /// Placement of ad or identifier of the ad in the app /// Error reason for no ad available /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewAdEvent(GAAdAction adAction, GAAdType adType, string adSdkName, string adPlacement, GAAdError noAdReason, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Ads.NewEvent(adAction, adType, adSdkName, adPlacement, noAdReason, customFields, mergeFields); } /// /// Track fill-rate of you ads. /// /// Action of ad (for example loaded, show). /// Type of ad (for video, interstitial). /// Name of ad SDK. /// Placement of ad or identifier of the ad in the app public static void NewAdEvent(GAAdAction adAction, GAAdType adType, string adSdkName, string adPlacement) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Ads.NewEvent(adAction, adType, adSdkName, adPlacement, null, false); } /// /// Track fill-rate of you ads. /// /// Action of ad (for example loaded, show). /// Type of ad (for video, interstitial). /// Name of ad SDK. /// Placement of ad or identifier of the ad in the app /// Custom fields to add to the event. Dictionary of key-value pairs. Only string or numbers allowed as values. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void NewAdEvent(GAAdAction adAction, GAAdType adType, string adSdkName, string adPlacement, IDictionary customFields, bool mergeFields = false) { if (!GameAnalytics._hasInitializeBeenCalled) { Debug.LogError("GameAnalytics: REMEMBER THE SDK NEEDS TO BE MANUALLY INITIALIZED NOW"); return; } GA_Ads.NewEvent(adAction, adType, adSdkName, adPlacement, customFields, mergeFields); } /// /// Sets the custom identifier. /// /// User identifier. public static void SetCustomId(string userId) { Debug.Log ("Initializing with custom id: " + userId); GA_Wrapper.SetCustomUserId (userId); } /// /// gets the current user id /// public static String GetUserId() { return GA_Wrapper.getUserId(); } /// /// Sets the enabled manual session handling. /// /// If set to true enabled. public static void SetEnabledManualSessionHandling(bool enabled) { GA_Wrapper.SetEnabledManualSessionHandling(enabled); } /// /// Sets the enabled event submission. /// /// If set to true enabled. public static void SetEnabledEventSubmission(bool enabled) { GA_Wrapper.SetEnabledEventSubmission(enabled); } /// /// Sets the enabled event submission. /// /// If set to true enabled. /// If set to true events will be cached locally even if submission is disabled. public static void SetEnabledEventSubmission(bool enabled, bool doCache) { GA_Wrapper.SetEnabledEventSubmission(enabled, doCache); } /// /// Starts the session. /// public static void StartSession() { GA_Wrapper.StartSession(); } /// /// Ends the session. /// public static void EndSession() { GA_Wrapper.EndSession(); } /// /// Set 1st custom dimension. /// /// One of the available dimension values set in Settings (Setup tab). Will persist cross session. Set to null to remove again. public static void SetCustomDimension01(string customDimension) { GA_Setup.SetCustomDimension01(customDimension); } /// /// Set 2nd custom dimension. /// /// One of the available dimension values set in Settings (Setup tab). Will persist cross session. Set to null to remove again. public static void SetCustomDimension02(string customDimension) { GA_Setup.SetCustomDimension02(customDimension); } /// /// Set 3rd custom dimension. /// /// One of the available dimension values set in Settings (Setup tab). Will persist cross session. Set to null to remove again. public static void SetCustomDimension03(string customDimension) { GA_Setup.SetCustomDimension03(customDimension); } /// /// Set global custom event fields. /// /// Set of key-value pairs to be used as global custom event fields to be added to all events. Custom fields are only stored in raw events and can only be used for data export (i.e. not visible in the tool). public static void SetGlobalCustomEventFields(IDictionary customFields) { GA_Setup.SetGlobalCustomEventFields(customFields); } // ----------------------- REMOTE CONFIGS ---------------------- // public static event Action OnRemoteConfigsUpdatedEvent; public void OnRemoteConfigsUpdated() { if(OnRemoteConfigsUpdatedEvent != null) { OnRemoteConfigsUpdatedEvent(); } } public static void RemoteConfigsUpdated() { if (OnRemoteConfigsUpdatedEvent != null) { OnRemoteConfigsUpdatedEvent(); } } public static string GetRemoteConfigsValueAsString(string key) { return GetRemoteConfigsValueAsString(key, null); } public static string GetRemoteConfigsValueAsString(string key, string defaultValue) { return GA_Wrapper.GetRemoteConfigsValueAsString(key, defaultValue); } public static bool IsRemoteConfigsReady() { return GA_Wrapper.IsRemoteConfigsReady(); } public static string GetRemoteConfigsContentAsString() { return GA_Wrapper.GetRemoteConfigsContentAsString(); } // ----------------------- A/B TESTING ---------------------- // public static string GetABTestingId() { return GA_Wrapper.GetABTestingId(); } public static string GetABTestingVariantId() { return GA_Wrapper.GetABTestingVariantId(); } public static void StartTimer(string key) { GA_Wrapper.StartTimer(key); } public static void PauseTimer(string key) { GA_Wrapper.PauseTimer(key); } public static void ResumeTimer(string key) { GA_Wrapper.ResumeTimer(key); } public static long StopTimer(string key) { return GA_Wrapper.StopTimer(key); } // ----------------------- IOS 14+ APP TRACKING TRANSPARENCY ---------------------- // public static void RequestTrackingAuthorization(IGameAnalyticsATTListener listener) { #if UNITY_IOS GameAnalyticsATTClient.Instance.RequestTrackingAuthorization(listener); #endif } public static void EnableAdvertisingIdTracking(bool flag) { #if UNITY_ANDROID && (!UNITY_EDITOR) GA_Wrapper.enableGAIDTracking(flag); #endif } private static string GetUnityVersion() { string unityVersion = ""; string[] splitUnityVersion = Application.unityVersion.Split('.'); for(int i = 0; i < splitUnityVersion.Length; i++) { int result; if(int.TryParse(splitUnityVersion[i], out result)) { if(i == 0) unityVersion = splitUnityVersion[i]; else unityVersion += "." + splitUnityVersion[i]; } else { string[] regexVersion = System.Text.RegularExpressions.Regex.Split(splitUnityVersion[i], "[^\\d]+"); if(regexVersion.Length > 0 && int.TryParse(regexVersion[0], out result)) { unityVersion += "." + regexVersion[0]; } } } return unityVersion; } private static int GetPlatformIndex() { int result = -1; RuntimePlatform platform = Application.platform; if(platform == RuntimePlatform.IPhonePlayer) { if(!SettingsGA.Platforms.Contains(platform)) { result = SettingsGA.Platforms.IndexOf(RuntimePlatform.tvOS); } else { result = SettingsGA.Platforms.IndexOf(platform); } } else if(platform == RuntimePlatform.tvOS) { if(!SettingsGA.Platforms.Contains(platform)) { result = SettingsGA.Platforms.IndexOf(RuntimePlatform.IPhonePlayer); } else { result = SettingsGA.Platforms.IndexOf(platform); } } // HACK: To also check for RuntimePlatform.MetroPlayerARM, RuntimePlatform.MetroPlayerX64 and RuntimePlatform.MetroPlayerX86 which are deprecated but have same value as the WSA enums else if (platform == RuntimePlatform.WSAPlayerARM || platform == RuntimePlatform.WSAPlayerX64 || platform == RuntimePlatform.WSAPlayerX86 || ((int)platform == (int)RuntimePlatform.WSAPlayerARM) || ((int)platform == (int)RuntimePlatform.WSAPlayerX64) || ((int)platform == (int)RuntimePlatform.WSAPlayerX86)) { result = SettingsGA.Platforms.IndexOf(RuntimePlatform.WSAPlayerARM); } else { result = SettingsGA.Platforms.IndexOf(platform); } return result; } #if UNITY_EDITOR /// /// Dynamic search for a file. /// /// Returns the Unity path to a specified file. /// File name including extension e.g. image.png public static string WhereIs(string _file, string _type) { #if UNITY_SAMSUNGTV return ""; #else string[] guids = AssetDatabase.FindAssets("t:" + _type); foreach(string g in guids) { string p = AssetDatabase.GUIDToAssetPath(g); if(p.EndsWith(_file)) { return p; } } return ""; #endif } public static void HierarchyWindowCallback(int instanceID, Rect selectionRect) { GameObject go = (GameObject)EditorUtility.InstanceIDToObject(instanceID); if(go != null && go.GetComponent() != null) { float addX = 0; if(go.GetComponent("PlayMakerFSM") != null) addX = selectionRect.height + 2; if(GameAnalytics.SettingsGA.Logo == null) { GameAnalytics.SettingsGA.Logo = (Texture2D)AssetDatabase.LoadAssetAtPath(WhereIs("gaLogo.png", "Texture2D"), typeof(Texture2D)); } Graphics.DrawTexture(new Rect(GUILayoutUtility.GetLastRect().width - selectionRect.height - 5 - addX, selectionRect.y, selectionRect.height, selectionRect.height), GameAnalytics.SettingsGA.Logo); } } #endif /// /// Sets the build for all platforms. /// /// Build. public static void SetBuildAllPlatforms(string build) { for (int i = 0; i < GameAnalytics.SettingsGA.Build.Count; i++) { GameAnalytics.SettingsGA.Build[i] = build; } } } }