From ac50190ef48107032e6c894c261e6290da2d3be6 Mon Sep 17 00:00:00 2001 From: tung_tung Date: Fri, 15 Nov 2024 15:00:16 +0700 Subject: [PATCH 01/24] update unity android --- unity/Assets/Plugins/Emotiv-Unity-Plugin | 2 +- unity/Assets/SimpleExample.cs | 87 +++++++++++++++++++++++- unity/Packages/manifest.json | 20 +++--- 3 files changed, 97 insertions(+), 12 deletions(-) diff --git a/unity/Assets/Plugins/Emotiv-Unity-Plugin b/unity/Assets/Plugins/Emotiv-Unity-Plugin index fcc73f5..d958113 160000 --- a/unity/Assets/Plugins/Emotiv-Unity-Plugin +++ b/unity/Assets/Plugins/Emotiv-Unity-Plugin @@ -1 +1 @@ -Subproject commit fcc73f532d8830bbcb37626a1ea8e3bc271a92ed +Subproject commit d958113a38fc69ac0dd913d9e0bbee36208e2279 diff --git a/unity/Assets/SimpleExample.cs b/unity/Assets/SimpleExample.cs index 1e843dd..9124fb8 100644 --- a/unity/Assets/SimpleExample.cs +++ b/unity/Assets/SimpleExample.cs @@ -39,15 +39,98 @@ public class SimpleExample : MonoBehaviour [SerializeField] public Toggle SYSToggle; [SerializeField] public Text MessageLog; - + + // for android + #if UNITY_ANDROID + const string pluginName = "com.emotiv.unity.CortexLibManager"; + + private static AndroidJavaClass _pluginClass; + private static AndroidJavaObject _pluginInstance; + private AndroidJavaObject currentActivity; + public static AndroidJavaClass PluginClass + { + get { + if (_pluginClass==null) + { + _pluginClass = new AndroidJavaClass(pluginName); + } + return _pluginClass; + } + } + + public static AndroidJavaObject PluginInstance + { + get { + if (_pluginInstance==null) + { + _pluginInstance = PluginClass.CallStatic("getInstance"); + } + return _pluginInstance; + } + } + private const string FineLocationPermission = "android.permission.ACCESS_FINE_LOCATION"; + private const string BluetoothScanPermission = "android.permission.BLUETOOTH_SCAN"; + private const string BluetoothConnectPermission = "android.permission.BLUETOOTH_CONNECT"; + + IEnumerator RequestPermissions() + { + yield return new WaitForSeconds(1f); // Wait for a second to ensure the app is fully initialized + + if (!HasPermission(FineLocationPermission)) + { + RequestPermission(FineLocationPermission); + } + + if (!HasPermission(BluetoothScanPermission)) + { + RequestPermission(BluetoothScanPermission); + } + + if (!HasPermission(BluetoothConnectPermission)) + { + RequestPermission(BluetoothConnectPermission); + } + } + + private static bool HasPermission(string permissionName) + { + return Permission.HasUserAuthorizedPermission(permissionName); + } + + private static void RequestPermission(string permissionName) { + if (Permission.HasUserAuthorizedPermission(permissionName)) + { + Debug.Log("Permission " + permissionName + " is authorized"); + } + else + { + // We do not have permission to use the microphone. + // Ask for permission or proceed without the functionality enabled. + Permission.RequestUserPermission(permissionName); + } + } + #endif void Start() { // init EmotivUnityItf without data buffer using _eItf.Init(_clientId, _clientSecret, _appName, _appVersion, _isDataBufferUsing); - // Start + // load cortex lib for android + #if UNITY_ANDROID + AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); + // Get the current activity + currentActivity = unityPlayer.GetStatic("currentActivity"); + // Open :request permissions + // StartCoroutine(RequestPermissions()); + + _eItf.Start(currentActivity.Call("getApplication")); + // if not mobile platform, start cortex + #elif UNITY_IOS + // TODO: load cortex lib for ios + #else _eItf.Start(); + #endif } diff --git a/unity/Packages/manifest.json b/unity/Packages/manifest.json index 11eab1a..75e8bc8 100644 --- a/unity/Packages/manifest.json +++ b/unity/Packages/manifest.json @@ -2,16 +2,18 @@ "dependencies": { "com.unity.2d.sprite": "1.0.0", "com.unity.2d.tilemap": "1.0.0", - "com.unity.ads": "3.7.5", - "com.unity.analytics": "3.6.12", - "com.unity.ide.rider": "3.0.13", - "com.unity.ide.visualstudio": "2.0.14", + "com.unity.ads": "4.4.2", + "com.unity.ai.navigation": "2.0.0", + "com.unity.analytics": "3.8.1", + "com.unity.ide.rider": "3.0.28", + "com.unity.ide.visualstudio": "2.0.22", "com.unity.ide.vscode": "1.2.5", - "com.unity.test-framework": "1.1.31", - "com.unity.textmeshpro": "3.0.6", - "com.unity.timeline": "1.6.4", - "com.unity.ugui": "1.0.0", - "com.unity.xr.legacyinputhelpers": "2.1.9", + "com.unity.mobile.android-logcat": "1.4.2", + "com.unity.test-framework": "1.3.9", + "com.unity.timeline": "1.8.6", + "com.unity.ugui": "2.0.0", + "com.unity.xr.legacyinputhelpers": "2.1.10", + "com.unity.modules.accessibility": "1.0.0", "com.unity.modules.ai": "1.0.0", "com.unity.modules.androidjni": "1.0.0", "com.unity.modules.animation": "1.0.0", From 169d383e7ff227941593c36122c9404be024fe68 Mon Sep 17 00:00:00 2001 From: tung_tung Date: Fri, 15 Nov 2024 17:11:09 +0700 Subject: [PATCH 02/24] add code to open webview --- unity/Assets/Plugins/Emotiv-Unity-Plugin | 2 +- unity/Assets/SimpleExample.cs | 112 ++++++++++++++++++++++- 2 files changed, 112 insertions(+), 2 deletions(-) diff --git a/unity/Assets/Plugins/Emotiv-Unity-Plugin b/unity/Assets/Plugins/Emotiv-Unity-Plugin index d958113..3272195 160000 --- a/unity/Assets/Plugins/Emotiv-Unity-Plugin +++ b/unity/Assets/Plugins/Emotiv-Unity-Plugin @@ -1 +1 @@ -Subproject commit d958113a38fc69ac0dd913d9e0bbee36208e2279 +Subproject commit 32721957b19bacd861f4d591c0733a436b127e02 diff --git a/unity/Assets/SimpleExample.cs b/unity/Assets/SimpleExample.cs index 9124fb8..3977f7f 100644 --- a/unity/Assets/SimpleExample.cs +++ b/unity/Assets/SimpleExample.cs @@ -3,7 +3,10 @@ using UnityEngine; using EmotivUnityPlugin; using UnityEngine.UI; - +#if UNITY_ANDROID +using UnityEngine.Android; +using Gpm.WebView; +#endif public class SimpleExample : MonoBehaviour { @@ -110,6 +113,36 @@ private static void RequestPermission(string permissionName) { } } #endif + + // Popup default +public void ShowUrlPopupDefault() +{ + string server = "cerebrum.emotivcloud.com"; + string urlRequest = "https://" + server + "/api/oauth/authorize/" ; + + GpmWebView.ShowUrl( + urlRequest, + new GpmWebViewRequest.Configuration() + { + style = GpmWebViewStyle.POPUP, + orientation = GpmOrientation.UNSPECIFIED, + isClearCookie = true, + isClearCache = true, + isNavigationBarVisible = true, + isCloseButtonVisible = true, + supportMultipleWindows = true, +#if UNITY_IOS + contentMode = GpmWebViewContentMode.MOBILE, + isMaskViewVisible = true, +#endif + }, + // See the end of the code example + OnCallback, + new List() + { + "USER_ CUSTOM_SCHEME" + }); +} void Start() { @@ -151,6 +184,15 @@ void Update() MessageLog.color = Color.black; } MessageLog.text = _eItf.MessageLog; + + // check login status + if (_eItf.GetConnectToCortexState() == ConnectToCortexStates.Login_notYet) { + #if UNITY_ANDROID + UnityEngine.Debug.Log("ShowUrlPopupDefault"); + ShowUrlPopupDefault(); + #endif + } + if (!_eItf.IsAuthorizedOK) return; @@ -411,4 +453,72 @@ private List GetStreamsList() { } return _streams; } + + private void OnCallback( + GpmWebViewCallback.CallbackType callbackType, + string data, + GpmWebViewError error) + { + Debug.Log("OnCallback: " + callbackType + " data: " + data + " error: " + error); + switch (callbackType) + { + case GpmWebViewCallback.CallbackType.Open: + if (error != null) + { + Debug.LogFormat("Fail to open WebView. Error:{0}", error); + } + break; + case GpmWebViewCallback.CallbackType.Close: + if (error != null) + { + Debug.LogFormat("Fail to close WebView. Error:{0}", error); + } + break; + case GpmWebViewCallback.CallbackType.PageStarted: + if (string.IsNullOrEmpty(data) == false) + { + Debug.LogFormat("PageStarted Url : {0}", data); + } + break; + case GpmWebViewCallback.CallbackType.PageLoad: + if (string.IsNullOrEmpty(data) == false) + { + Debug.LogFormat("Loaded Page:{0}", data); + } + break; + case GpmWebViewCallback.CallbackType.MultiWindowOpen: + Debug.Log("MultiWindowOpen"); + break; + case GpmWebViewCallback.CallbackType.MultiWindowClose: + Debug.Log("MultiWindowClose"); + break; + case GpmWebViewCallback.CallbackType.Scheme: + if (error == null) + { + if (data.Equals("USER_ CUSTOM_SCHEME") == true || data.Contains("CUSTOM_SCHEME") == true) + { + Debug.Log(string.Format("scheme:{0}", data)); + } + } + else + { + Debug.Log(string.Format("Fail to custom scheme. Error:{0}", error)); + } + break; + case GpmWebViewCallback.CallbackType.GoBack: + Debug.Log("GoBack"); + break; + case GpmWebViewCallback.CallbackType.GoForward: + Debug.Log("GoForward"); + break; + case GpmWebViewCallback.CallbackType.ExecuteJavascript: + Debug.LogFormat("ExecuteJavascript data : {0}, error : {1}", data, error); + break; + #if UNITY_ANDROID + case GpmWebViewCallback.CallbackType.BackButtonClose: + Debug.Log("BackButtonClose"); + break; + #endif + } + } } From 2c39c6a0321dc6b986e0365725ba29465d9887f8 Mon Sep 17 00:00:00 2001 From: tung_tung Date: Thu, 21 Nov 2024 19:31:45 +0700 Subject: [PATCH 03/24] update unity example with private login --- .../Plugins/Android/AndroidManifest.xml | 25 ++ .../Android/baseProjectTemplate.gradle | 13 + .../Plugins/Android/gradleTemplate.properties | 6 + .../Plugins/Android/launcherTemplate.gradle | 81 ++++ .../Plugins/Android/mainTemplate.gradle | 74 ++++ unity/Assets/Plugins/AppConfig.cs | 4 +- unity/Assets/Plugins/ConnectToCortex.cs | 5 +- unity/Assets/Plugins/DataProcessing.cs | 6 + unity/Assets/Plugins/Emotiv-Unity-Plugin | 2 +- unity/Assets/SimpleExample.cs | 194 +++------ unity/Assets/SimpleExample.unity | 400 +++++++++++------ .../ProjectSettings/EditorBuildSettings.asset | 6 +- .../PackageManagerSettings.asset | 8 +- unity/ProjectSettings/ProjectSettings.asset | 407 ++++++++++++++---- unity/ProjectSettings/ProjectVersion.txt | 4 +- 15 files changed, 890 insertions(+), 345 deletions(-) create mode 100644 unity/Assets/Plugins/Android/AndroidManifest.xml create mode 100644 unity/Assets/Plugins/Android/baseProjectTemplate.gradle create mode 100644 unity/Assets/Plugins/Android/gradleTemplate.properties create mode 100644 unity/Assets/Plugins/Android/launcherTemplate.gradle create mode 100644 unity/Assets/Plugins/Android/mainTemplate.gradle diff --git a/unity/Assets/Plugins/Android/AndroidManifest.xml b/unity/Assets/Plugins/Android/AndroidManifest.xml new file mode 100644 index 0000000..b8174c1 --- /dev/null +++ b/unity/Assets/Plugins/Android/AndroidManifest.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/unity/Assets/Plugins/Android/baseProjectTemplate.gradle b/unity/Assets/Plugins/Android/baseProjectTemplate.gradle new file mode 100644 index 0000000..51cd761 --- /dev/null +++ b/unity/Assets/Plugins/Android/baseProjectTemplate.gradle @@ -0,0 +1,13 @@ +plugins { + // If you are changing the Android Gradle Plugin version, make sure it is compatible with the Gradle version preinstalled with Unity + // See which Gradle version is preinstalled with Unity here https://docs.unity3d.com/Manual/android-gradle-overview.html + // See official Gradle and Android Gradle Plugin compatibility table here https://developer.android.com/studio/releases/gradle-plugin#updating-gradle + // To specify a custom Gradle version in Unity, go do "Preferences > External Tools", uncheck "Gradle Installed with Unity (recommended)" and specify a path to a custom Gradle version + id 'com.android.application' version '7.3.1' apply false + id 'com.android.library' version '7.3.1' apply false + **BUILD_SCRIPT_DEPS** +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/unity/Assets/Plugins/Android/gradleTemplate.properties b/unity/Assets/Plugins/Android/gradleTemplate.properties new file mode 100644 index 0000000..ef2d8f0 --- /dev/null +++ b/unity/Assets/Plugins/Android/gradleTemplate.properties @@ -0,0 +1,6 @@ +org.gradle.jvmargs=-Xmx**JVM_HEAP_SIZE**M +org.gradle.parallel=true +android.useAndroidX=true +android.enableJetifier=true +unityStreamingAssets=**STREAMING_ASSETS** +**ADDITIONAL_PROPERTIES** diff --git a/unity/Assets/Plugins/Android/launcherTemplate.gradle b/unity/Assets/Plugins/Android/launcherTemplate.gradle new file mode 100644 index 0000000..69d2e9a --- /dev/null +++ b/unity/Assets/Plugins/Android/launcherTemplate.gradle @@ -0,0 +1,81 @@ +apply plugin: 'com.android.application' + +dependencies { + implementation project(':unityLibrary') + } + +android { + ndkPath "**NDKPATH**" + namespace "**NAMESPACE**" + + compileSdkVersion **APIVERSION** + buildToolsVersion '**BUILDTOOLS**' + + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } + + defaultConfig { + minSdkVersion 24 + targetSdkVersion **TARGETSDKVERSION** + applicationId '**APPLICATIONID**' + ndk { + abiFilters **ABIFILTERS** + } + versionCode **VERSIONCODE** + versionName '**VERSIONNAME**' + } + + aaptOptions { + noCompress = **BUILTIN_NOCOMPRESS** + unityStreamingAssets.tokenize(', ') + ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~" + }**SIGN** + + lintOptions { + abortOnError false + } + + buildTypes { + debug { + minifyEnabled **MINIFY_DEBUG** + proguardFiles getDefaultProguardFile('proguard-android.txt')**SIGNCONFIG** + jniDebuggable true + } + release { + minifyEnabled **MINIFY_RELEASE** + proguardFiles getDefaultProguardFile('proguard-android.txt')**SIGNCONFIG** + } + } + packagingOptions { + exclude 'META-INF/kotlinx_coroutines_core.version' + exclude 'META-INF/androidx.lifecycle_lifecycle-livedata-core.version' + exclude 'kotlin/internal/internal.kotlin_builtins' + exclude 'META-INF/androidx.lifecycle_lifecycle-viewmodel-savedstate.version' + exclude 'META-INF/androidx.appcompat_appcompat.version' + exclude 'kotlin/reflect/reflect.kotlin_builtins' + exclude 'META-INF/*.version' + exclude 'DebugProbesKt.bin' + exclude 'kotlin/collections/*.kotlin_builtins' + exclude 'kotlin/**/*.kotlin_builtins' + exclude 'kotlin/*.kotlin_builtins' + } + **PACKAGING_OPTIONS****PLAY_ASSET_PACKS****SPLITS** +**BUILT_APK_LOCATION** + bundle { + language { + enableSplit = false + } + density { + enableSplit = false + } + abi { + enableSplit = true + } + texture { + enableSplit = true + } + } + + **GOOGLE_PLAY_DEPENDENCIES** +}**SPLITS_VERSION_CODE****LAUNCHER_SOURCE_BUILD_SETUP** diff --git a/unity/Assets/Plugins/Android/mainTemplate.gradle b/unity/Assets/Plugins/Android/mainTemplate.gradle new file mode 100644 index 0000000..6ef850d --- /dev/null +++ b/unity/Assets/Plugins/Android/mainTemplate.gradle @@ -0,0 +1,74 @@ +apply plugin: 'com.android.library' +**APPLY_PLUGINS** + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'androidx.appcompat:appcompat:1.5.1' +**DEPS**} + +buildscript { + repositories { + google() + mavenCentral() + } + + // dependencies { + // classpath "com.android.tools.build:gradle:4.2.1" + // } +} + +repositories { + google() + mavenCentral() +} + +android { + ndkPath "**NDKPATH**" + namespace "com.unity3d.player" + + compileSdkVersion **APIVERSION** + buildToolsVersion '**BUILDTOOLS**' + + compileOptions { + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 + } + + defaultConfig { + minSdkVersion 24 + targetSdkVersion **TARGETSDKVERSION** + ndk { + abiFilters **ABIFILTERS** + } + versionCode **VERSIONCODE** + versionName '**VERSIONNAME**' + consumerProguardFiles 'proguard-unity.txt'**USER_PROGUARD** +**DEFAULT_CONFIG_SETUP** + } + + lintOptions { + abortOnError false + } + + aaptOptions { + noCompress = **BUILTIN_NOCOMPRESS** + unityStreamingAssets.tokenize(', ') + ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~" + } + packagingOptions { + exclude 'META-INF/kotlinx_coroutines_core.version' + exclude 'META-INF/androidx.lifecycle_lifecycle-livedata-core.version' + exclude 'kotlin/internal/internal.kotlin_builtins' + exclude 'META-INF/androidx.lifecycle_lifecycle-viewmodel-savedstate.version' + exclude 'META-INF/androidx.appcompat_appcompat.version' + exclude 'kotlin/reflect/reflect.kotlin_builtins' + exclude 'META-INF/*.version' + exclude 'DebugProbesKt.bin' + exclude 'kotlin/collections/*.kotlin_builtins' + exclude 'kotlin/**/*.kotlin_builtins' + exclude 'kotlin/*.kotlin_builtins' + } + **PACKAGING_OPTIONS** +} +**IL_CPP_BUILD_SETUP** +**SOURCE_BUILD_SETUP** +**EXTERNAL_SOURCES** diff --git a/unity/Assets/Plugins/AppConfig.cs b/unity/Assets/Plugins/AppConfig.cs index 45afa83..2f2a997 100644 --- a/unity/Assets/Plugins/AppConfig.cs +++ b/unity/Assets/Plugins/AppConfig.cs @@ -1,7 +1,7 @@ /// /// Contain configuration of a specific App. /// -static class AppConfig +public static class AppConfig { public static string AppUrl = "wss://localhost:6868"; public static string AppName = "UnityApp"; @@ -9,5 +9,7 @@ static class AppConfig // Please fill the clientId and client Secret of your application before starting. public static string ClientId = ""; public static string ClientSecret = ""; + public static string UserName = ""; + public static string Password = ""; public static string AppVersion = "3.3.0"; } \ No newline at end of file diff --git a/unity/Assets/Plugins/ConnectToCortex.cs b/unity/Assets/Plugins/ConnectToCortex.cs index 362ebbe..aee6d61 100644 --- a/unity/Assets/Plugins/ConnectToCortex.cs +++ b/unity/Assets/Plugins/ConnectToCortex.cs @@ -16,11 +16,14 @@ void Start() { // set Application configuration _dataStream.SetAppConfig(AppConfig.ClientId, AppConfig.ClientSecret, - AppConfig.AppVersion, AppConfig.AppName, AppConfig.AppName, AppConfig.AppUrl, + AppConfig.AppVersion, AppConfig.AppName, AppConfig.UserName, AppConfig.Password, + AppConfig.AppName, AppConfig.AppUrl, EmotivAppslicationPath()); // Init logger + #if !UNITY_ANDROID && !UNITY_IOS _logger.Init(); + #endif Debug.Log("Configure BrainViz - PRODUCT SERVER - version: " +AppConfig.AppVersion); diff --git a/unity/Assets/Plugins/DataProcessing.cs b/unity/Assets/Plugins/DataProcessing.cs index 2a6b70d..b82541a 100644 --- a/unity/Assets/Plugins/DataProcessing.cs +++ b/unity/Assets/Plugins/DataProcessing.cs @@ -71,6 +71,7 @@ public DataProcessing() { DataStreamManager.Instance.SessionActivatedOK += OnSessionActivatedOK; DataStreamManager.Instance.LicenseValidTo += onLicenseValidTo; + DataStreamManager.Instance.MessageQueryHeadsetOK +=OnMessageQueryHeadsetOK; } ~DataProcessing() { @@ -414,6 +415,11 @@ private void OnSessionActivatedOK(object sender, string headsetID) } } + private void OnMessageQueryHeadsetOK(object sender, string msg) + { + // TODO: Implement it later + } + private void onLicenseValidTo(object sender, DateTime validToDate) { DateTime curUTC_Now = DateTime.UtcNow; diff --git a/unity/Assets/Plugins/Emotiv-Unity-Plugin b/unity/Assets/Plugins/Emotiv-Unity-Plugin index 3272195..56aeabd 160000 --- a/unity/Assets/Plugins/Emotiv-Unity-Plugin +++ b/unity/Assets/Plugins/Emotiv-Unity-Plugin @@ -1 +1 @@ -Subproject commit 32721957b19bacd861f4d591c0733a436b127e02 +Subproject commit 56aeabd20d2b8a974c5e8a7da558b9c7bde979de diff --git a/unity/Assets/SimpleExample.cs b/unity/Assets/SimpleExample.cs index 3977f7f..8fa8f04 100644 --- a/unity/Assets/SimpleExample.cs +++ b/unity/Assets/SimpleExample.cs @@ -3,9 +3,10 @@ using UnityEngine; using EmotivUnityPlugin; using UnityEngine.UI; +using System; + #if UNITY_ANDROID using UnityEngine.Android; -using Gpm.WebView; #endif public class SimpleExample : MonoBehaviour { @@ -15,6 +16,8 @@ public class SimpleExample : MonoBehaviour private string _clientSecret = ""; private string _appName = "UnityApp"; private string _appVersion = "3.3.0"; + private bool _isStarted = false; + EmotivUnityItf _eItf = EmotivUnityItf.Instance; float _timerDataUpdate = 0; @@ -74,6 +77,27 @@ public static AndroidJavaObject PluginInstance private const string FineLocationPermission = "android.permission.ACCESS_FINE_LOCATION"; private const string BluetoothScanPermission = "android.permission.BLUETOOTH_SCAN"; private const string BluetoothConnectPermission = "android.permission.BLUETOOTH_CONNECT"; + private const string WriteExternalStoragePermission = "android.permission.WRITE_EXTERNAL_STORAGE"; + + private readonly string[] permissions = { + FineLocationPermission, + BluetoothScanPermission, + BluetoothConnectPermission, + WriteExternalStoragePermission + }; + + private bool HasAllPermissions() + { + foreach (string permission in permissions) + { + if (!Permission.HasUserAuthorizedPermission(permission)) + { + return false; + } + } + return true; + } + IEnumerator RequestPermissions() { @@ -93,6 +117,10 @@ IEnumerator RequestPermissions() { RequestPermission(BluetoothConnectPermission); } + if (!HasPermission(WriteExternalStoragePermission)) + { + RequestPermission(WriteExternalStoragePermission); + } } private static bool HasPermission(string permissionName) @@ -113,55 +141,14 @@ private static void RequestPermission(string permissionName) { } } #endif - - // Popup default -public void ShowUrlPopupDefault() -{ - string server = "cerebrum.emotivcloud.com"; - string urlRequest = "https://" + server + "/api/oauth/authorize/" ; - - GpmWebView.ShowUrl( - urlRequest, - new GpmWebViewRequest.Configuration() - { - style = GpmWebViewStyle.POPUP, - orientation = GpmOrientation.UNSPECIFIED, - isClearCookie = true, - isClearCache = true, - isNavigationBarVisible = true, - isCloseButtonVisible = true, - supportMultipleWindows = true, -#if UNITY_IOS - contentMode = GpmWebViewContentMode.MOBILE, - isMaskViewVisible = true, -#endif - }, - // See the end of the code example - OnCallback, - new List() - { - "USER_ CUSTOM_SCHEME" - }); -} void Start() { // init EmotivUnityItf without data buffer using - _eItf.Init(_clientId, _clientSecret, _appName, _appVersion, _isDataBufferUsing); + _eItf.Init(AppConfig.ClientId, AppConfig.ClientSecret, _appName, _appVersion, AppConfig.UserName, AppConfig.Password, _isDataBufferUsing); - // load cortex lib for android - #if UNITY_ANDROID - AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); - // Get the current activity - currentActivity = unityPlayer.GetStatic("currentActivity"); - // Open :request permissions - // StartCoroutine(RequestPermissions()); - - _eItf.Start(currentActivity.Call("getApplication")); - // if not mobile platform, start cortex - #elif UNITY_IOS - // TODO: load cortex lib for ios - #else + #if !UNITY_ANDROID && !UNITY_IOS + UnityEngine.Debug.Log("SimpleExp: Start EmotivUnityItf for test"); _eItf.Start(); #endif @@ -185,21 +172,28 @@ void Update() } MessageLog.text = _eItf.MessageLog; - // check login status - if (_eItf.GetConnectToCortexState() == ConnectToCortexStates.Login_notYet) { - #if UNITY_ANDROID - UnityEngine.Debug.Log("ShowUrlPopupDefault"); - ShowUrlPopupDefault(); - #endif + #if UNITY_ANDROID + if (HasAllPermissions() && !_isStarted) { + AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); + // Get the current activity + currentActivity = unityPlayer.GetStatic("currentActivity"); + _eItf.Start(currentActivity); + + _isStarted = true; + } + else if (!_isStarted) { + StartCoroutine(RequestPermissions()); } + #endif if (!_eItf.IsAuthorizedOK) return; // Check to call scan headset if no session is created and no scanning headset if (!_eItf.IsSessionCreated && !DataStreamManager.Instance.IsHeadsetScanning) { + // UnityEngine.Debug.Log("qqqqqqq SimpleExp: No scanning headset"); // Start scanning headset at headset list screen - DataStreamManager.Instance.ScanHeadsets(); + // DataStreamManager.Instance.ScanHeadsets(); } // Check buttons interactable @@ -228,6 +222,15 @@ void Update() } + /// + /// create session + /// + public void onQueryHeadsetBtnClick() { + Debug.Log("onQueryHeadsetBtnClick"); + _eItf.QueryHeadsets(); + } + + /// /// create session /// @@ -248,9 +251,14 @@ public void onCreateSessionBtnClick() { /// public void onStartRecordBtnClick() { Debug.Log("onStartRecordBtnClick " + RecordTitle.text + ":" + RecordDescription.text); - if (_eItf.IsSessionCreated && !string.IsNullOrEmpty(RecordTitle.text)) + if (_eItf.IsSessionCreated) { - _eItf.StartRecord(RecordTitle.text, RecordDescription.text); + string recordTitle = RecordTitle.text; + if (string.IsNullOrEmpty(recordTitle)) { + recordTitle = "Record test_" + DateTime.Now.ToString("yyyyMMdd_HHmmss"); + } + + _eItf.StartRecord(recordTitle, RecordDescription.text); } else { UnityEngine.Debug.LogError("Can not start a record because there is no active session or record title is empty."); @@ -270,7 +278,15 @@ public void onStopRecordBtnClick() { /// public void onInjectMarkerBtnClick() { Debug.Log("onInjectMarkerBtnClick " + MarkerValue.text + ":" + MarkerLabel.text); - _eItf.InjectMarker(MarkerLabel.text, MarkerLabel.text); + String markerValue = MarkerValue.text; + String markerLabel = MarkerLabel.text; + if (string.IsNullOrEmpty(markerValue)) { + markerValue = DateTime.Now.ToString("ss"); + } + if (string.IsNullOrEmpty(markerLabel)) { + markerLabel = "Marker_" + markerValue; + } + _eItf.InjectMarker(markerLabel, markerValue); } /// @@ -453,72 +469,4 @@ private List GetStreamsList() { } return _streams; } - - private void OnCallback( - GpmWebViewCallback.CallbackType callbackType, - string data, - GpmWebViewError error) - { - Debug.Log("OnCallback: " + callbackType + " data: " + data + " error: " + error); - switch (callbackType) - { - case GpmWebViewCallback.CallbackType.Open: - if (error != null) - { - Debug.LogFormat("Fail to open WebView. Error:{0}", error); - } - break; - case GpmWebViewCallback.CallbackType.Close: - if (error != null) - { - Debug.LogFormat("Fail to close WebView. Error:{0}", error); - } - break; - case GpmWebViewCallback.CallbackType.PageStarted: - if (string.IsNullOrEmpty(data) == false) - { - Debug.LogFormat("PageStarted Url : {0}", data); - } - break; - case GpmWebViewCallback.CallbackType.PageLoad: - if (string.IsNullOrEmpty(data) == false) - { - Debug.LogFormat("Loaded Page:{0}", data); - } - break; - case GpmWebViewCallback.CallbackType.MultiWindowOpen: - Debug.Log("MultiWindowOpen"); - break; - case GpmWebViewCallback.CallbackType.MultiWindowClose: - Debug.Log("MultiWindowClose"); - break; - case GpmWebViewCallback.CallbackType.Scheme: - if (error == null) - { - if (data.Equals("USER_ CUSTOM_SCHEME") == true || data.Contains("CUSTOM_SCHEME") == true) - { - Debug.Log(string.Format("scheme:{0}", data)); - } - } - else - { - Debug.Log(string.Format("Fail to custom scheme. Error:{0}", error)); - } - break; - case GpmWebViewCallback.CallbackType.GoBack: - Debug.Log("GoBack"); - break; - case GpmWebViewCallback.CallbackType.GoForward: - Debug.Log("GoForward"); - break; - case GpmWebViewCallback.CallbackType.ExecuteJavascript: - Debug.LogFormat("ExecuteJavascript data : {0}, error : {1}", data, error); - break; - #if UNITY_ANDROID - case GpmWebViewCallback.CallbackType.BackButtonClose: - Debug.Log("BackButtonClose"); - break; - #endif - } - } } diff --git a/unity/Assets/SimpleExample.unity b/unity/Assets/SimpleExample.unity index 1bb5851..e596995 100644 --- a/unity/Assets/SimpleExample.unity +++ b/unity/Assets/SimpleExample.unity @@ -13,7 +13,7 @@ OcclusionCullingSettings: --- !u!104 &2 RenderSettings: m_ObjectHideFlags: 0 - serializedVersion: 9 + serializedVersion: 10 m_Fog: 0 m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} m_FogMode: 3 @@ -38,13 +38,12 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.44657826, g: 0.49641263, b: 0.57481676, a: 1} + m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} m_UseRadianceAmbientProbe: 0 --- !u!157 &3 LightmapSettings: m_ObjectHideFlags: 0 serializedVersion: 12 - m_GIWorkflowMode: 0 m_GISettings: serializedVersion: 2 m_BounceScale: 1 @@ -67,9 +66,6 @@ LightmapSettings: m_LightmapParameters: {fileID: 0} m_LightmapsBakeMode: 1 m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 m_ReflectionCompression: 2 m_MixedBakeMode: 2 m_BakeBackend: 1 @@ -104,7 +100,7 @@ NavMeshSettings: serializedVersion: 2 m_ObjectHideFlags: 0 m_BuildSettings: - serializedVersion: 2 + serializedVersion: 3 agentTypeID: 0 agentRadius: 0.5 agentHeight: 2 @@ -117,7 +113,7 @@ NavMeshSettings: cellSize: 0.16666667 manualTileSize: 0 tileSize: 256 - accuratePlacement: 0 + buildHeightMesh: 0 maxJobWorkers: 0 preserveTilesOutsideBounds: 0 debug: @@ -155,7 +151,6 @@ RectTransform: - {fileID: 1758277371} - {fileID: 2100215841} m_Father: {fileID: 2125002434} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -241,7 +236,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1488303794} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -317,7 +311,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1557808010} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -395,9 +388,9 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 133447285} + - {fileID: 1010245114} - {fileID: 551019253} m_Father: {fileID: 710725585} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -439,7 +432,6 @@ RectTransform: - {fileID: 434463975} - {fileID: 961304498} m_Father: {fileID: 261595418} - m_RootOrder: 7 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -614,7 +606,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1612297223} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -652,7 +643,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1856857883} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -734,7 +724,6 @@ RectTransform: m_Children: - {fileID: 1913673273} m_Father: {fileID: 63080123} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -764,7 +753,7 @@ MonoBehaviour: m_Colors: m_NormalColor: {r: 1, g: 1, b: 1, a: 1} m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_PressedColor: {r: 0.5882353, g: 0.49019608, b: 0.49019608, a: 1} m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} m_ColorMultiplier: 1 @@ -797,6 +786,18 @@ MonoBehaviour: m_StringArgument: m_BoolArgument: 0 m_CallState: 2 + - m_Target: {fileID: 0} + m_TargetAssemblyTypeName: + m_MethodName: + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 --- !u!114 &133447287 MonoBehaviour: m_ObjectHideFlags: 0 @@ -866,7 +867,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 85301051} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -946,7 +946,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 710725585} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -1068,7 +1067,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 551019253} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -1106,7 +1104,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1168726927} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1186,7 +1183,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1068889447} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -1265,7 +1261,6 @@ RectTransform: m_Children: - {fileID: 1071623413} m_Father: {fileID: 1180467785} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -1310,7 +1305,6 @@ RectTransform: - {fileID: 85301051} - {fileID: 2031637684} m_Father: {fileID: 710725585} - m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -1348,7 +1342,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1758277371} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -1426,7 +1419,6 @@ RectTransform: m_Children: - {fileID: 1630543238} m_Father: {fileID: 2125002434} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -1558,7 +1550,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1653936226} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -1639,7 +1630,6 @@ RectTransform: m_Children: - {fileID: 1761669424} m_Father: {fileID: 875480430} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -1715,7 +1705,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 85301051} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} @@ -1790,6 +1779,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} m_Name: m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 m_HorizontalAxis: Horizontal m_VerticalAxis: Vertical m_SubmitButton: Submit @@ -1819,13 +1809,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 454893002} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &467055382 GameObject: @@ -1858,7 +1848,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2083123983} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -1939,7 +1928,6 @@ RectTransform: m_Children: - {fileID: 1206442306} m_Father: {fileID: 1342805839} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -2015,7 +2003,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1699489637} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -2166,7 +2153,6 @@ RectTransform: - {fileID: 193944433} - {fileID: 1504786871} m_Father: {fileID: 63080123} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -2242,7 +2228,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 837114421} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -2322,7 +2307,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1045466942} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -2402,7 +2386,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1699353816} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -2479,7 +2462,6 @@ RectTransform: - {fileID: 1488303794} - {fileID: 950727119} m_Father: {fileID: 2125002434} - m_RootOrder: 6 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -2566,7 +2548,6 @@ RectTransform: - {fileID: 1337283229} - {fileID: 1175567019} m_Father: {fileID: 2125002434} - m_RootOrder: 9 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -2672,7 +2653,7 @@ MonoBehaviour: m_EditorClassIdentifier: m_UiScaleMode: 0 m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 + m_ScaleFactor: 1.8 m_ReferenceResolution: {x: 800, y: 600} m_ScreenMatchMode: 0 m_MatchWidthOrHeight: 0 @@ -2698,7 +2679,9 @@ Canvas: m_OverrideSorting: 0 m_OverridePixelPerfect: 0 m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 m_AdditionalShaderChannelsFlag: 0 + m_UpdateRectTransformForStandalone: 0 m_SortingLayerID: 0 m_SortingOrder: 0 m_TargetDisplay: 0 @@ -2721,7 +2704,6 @@ RectTransform: - {fileID: 2125002434} - {fileID: 261595418} m_Father: {fileID: 0} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -2788,7 +2770,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1795800894} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -2870,7 +2851,6 @@ RectTransform: m_Children: - {fileID: 920599117} m_Father: {fileID: 261595418} - m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -3002,7 +2982,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1361979634} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -3083,7 +3062,6 @@ RectTransform: m_Children: - {fileID: 2016998310} m_Father: {fileID: 1597588607} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -3161,7 +3139,6 @@ RectTransform: m_Children: - {fileID: 585186887} m_Father: {fileID: 1294068891} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -3295,7 +3272,6 @@ RectTransform: m_Children: - {fileID: 1421141051} m_Father: {fileID: 261595418} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -3427,7 +3403,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1361640634} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -3504,7 +3479,6 @@ RectTransform: - {fileID: 381735265} - {fileID: 1346795405} m_Father: {fileID: 2125002434} - m_RootOrder: 7 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -3590,7 +3564,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1045466942} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 0, y: 0.5} @@ -3666,7 +3639,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1208256995} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -3788,7 +3760,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1856857883} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -3826,7 +3797,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 763954933} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -3906,7 +3876,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 619861153} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -3986,7 +3955,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1699489637} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -4069,7 +4037,6 @@ RectTransform: - {fileID: 1386706006} - {fileID: 1180467785} m_Father: {fileID: 85301051} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 0} @@ -4184,9 +4151,17 @@ Camera: m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 m_SensorSize: {x: 36, y: 24} m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -4220,14 +4195,159 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 993173860} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 1, z: -10} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1010245113 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1010245114} + - component: {fileID: 1010245117} + - component: {fileID: 1010245116} + - component: {fileID: 1010245115} + m_Layer: 5 + m_Name: queryHeadset + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1010245114 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1010245113} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1525170755} + m_Father: {fileID: 63080123} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -34, y: 184} + m_SizeDelta: {x: 156.8, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1010245115 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1010245113} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.5849056, g: 0.488341, b: 0.488341, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1010245116} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 710725586} + m_TargetAssemblyTypeName: SimpleExample, Assembly-CSharp + m_MethodName: onQueryHeadsetBtnClick + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + - m_Target: {fileID: 0} + m_TargetAssemblyTypeName: + m_MethodName: + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1010245116 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1010245113} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1010245117 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1010245113} + m_CullTransparentMesh: 0 --- !u!1 &1013663468 GameObject: m_ObjectHideFlags: 0 @@ -4253,9 +4373,8 @@ Light: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1013663468} m_Enabled: 1 - serializedVersion: 10 + serializedVersion: 11 m_Type: 1 - m_Shape: 0 m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} m_Intensity: 1 m_Range: 10 @@ -4314,13 +4433,13 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1013663468} + serializedVersion: 2 m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} m_LocalPosition: {x: 0, y: 3, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} --- !u!1 &1034015603 GameObject: @@ -4353,7 +4472,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1936392979} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -4435,7 +4553,6 @@ RectTransform: - {fileID: 875881625} - {fileID: 603614981} m_Father: {fileID: 1478912065} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} @@ -4523,7 +4640,6 @@ RectTransform: m_Children: - {fileID: 218118564} m_Father: {fileID: 261595418} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -4655,7 +4771,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 226116846} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 0.2} @@ -4733,7 +4848,6 @@ RectTransform: m_Children: - {fileID: 203505603} m_Father: {fileID: 710725585} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -4835,7 +4949,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 689784487} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -4917,7 +5030,6 @@ RectTransform: m_Children: - {fileID: 226116846} m_Father: {fileID: 961304498} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -5042,7 +5154,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1465464182} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -5122,7 +5233,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 520015158} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -5200,7 +5310,6 @@ RectTransform: m_Children: - {fileID: 902216602} m_Father: {fileID: 261595418} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -5332,7 +5441,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1342805839} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -5412,7 +5520,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1448973720} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -5497,7 +5604,6 @@ RectTransform: - {fileID: 1699489637} - {fileID: 1448973720} m_Father: {fileID: 710725585} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -5536,7 +5642,6 @@ RectTransform: m_Children: - {fileID: 1482786070} m_Father: {fileID: 689784487} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -5613,7 +5718,6 @@ RectTransform: - {fileID: 520015158} - {fileID: 1225881386} m_Father: {fileID: 2125002434} - m_RootOrder: 10 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -5699,7 +5803,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 875480430} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -5779,7 +5882,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1572148113} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -5860,7 +5962,6 @@ RectTransform: m_Children: - {fileID: 846358782} m_Father: {fileID: 1361979634} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -5937,7 +6038,6 @@ RectTransform: - {fileID: 1361640634} - {fileID: 766856443} m_Father: {fileID: 2125002434} - m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -6025,7 +6125,6 @@ RectTransform: m_Children: - {fileID: 1478912065} m_Father: {fileID: 961304498} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -6163,7 +6262,6 @@ RectTransform: - {fileID: 1612297223} - {fileID: 1413624170} m_Father: {fileID: 2125002434} - m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -6201,7 +6299,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1396800669} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -6281,7 +6378,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 843511036} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -6363,7 +6459,6 @@ RectTransform: m_Children: - {fileID: 1488292738} m_Father: {fileID: 1294068891} - m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -6566,7 +6661,6 @@ RectTransform: - {fileID: 1930577271} - {fileID: 1231044580} m_Father: {fileID: 1294068891} - m_RootOrder: 6 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -6644,7 +6738,6 @@ RectTransform: m_Children: - {fileID: 1192925048} m_Father: {fileID: 261595418} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -6775,7 +6868,6 @@ RectTransform: m_Children: - {fileID: 1045466942} m_Father: {fileID: 1386706006} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} @@ -6813,7 +6905,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1337283229} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -6889,7 +6980,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1444111431} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -6970,7 +7060,6 @@ RectTransform: m_Children: - {fileID: 26972401} m_Father: {fileID: 619861153} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -7046,7 +7135,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 551019253} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -7095,6 +7183,85 @@ MonoBehaviour: m_VerticalOverflow: 0 m_LineSpacing: 1 m_Text: +--- !u!1 &1525170754 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1525170755} + - component: {fileID: 1525170757} + - component: {fileID: 1525170756} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1525170755 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1525170754} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1010245114} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1525170756 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1525170754} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.21960786, g: 0.21960786, b: 0.21960786, a: 0.95686275} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 16 + m_FontStyle: 1 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Query Headset +--- !u!222 &1525170757 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1525170754} + m_CullTransparentMesh: 0 --- !u!1 &1557808009 GameObject: m_ObjectHideFlags: 0 @@ -7128,7 +7295,6 @@ RectTransform: m_Children: - {fileID: 27332301} m_Father: {fileID: 1294068891} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -7236,8 +7402,7 @@ LightingSettings: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: Settings.lighting - serializedVersion: 4 - m_GIWorkflowMode: 0 + serializedVersion: 8 m_EnableBakedLightmaps: 1 m_EnableRealtimeLightmaps: 1 m_RealtimeEnvironmentLighting: 1 @@ -7247,6 +7412,8 @@ LightingSettings: m_UsingShadowmask: 1 m_BakeBackend: 1 m_LightmapMaxSize: 1024 + m_LightmapSizeFixed: 0 + m_UseMipmapLimits: 1 m_BakeResolution: 40 m_Padding: 2 m_LightmapCompression: 3 @@ -7264,19 +7431,16 @@ LightingSettings: m_RealtimeResolution: 2 m_ForceWhiteAlbedo: 0 m_ForceUpdates: 0 - m_FinalGather: 0 - m_FinalGatherRayCount: 256 - m_FinalGatherFiltering: 1 m_PVRCulling: 1 m_PVRSampling: 1 m_PVRDirectSampleCount: 32 - m_PVRSampleCount: 500 - m_PVREnvironmentSampleCount: 500 + m_PVRSampleCount: 512 + m_PVREnvironmentSampleCount: 512 m_PVREnvironmentReferencePointCount: 2048 m_LightProbeSampleCountMultiplier: 4 m_PVRBounces: 2 m_PVRMinBounces: 2 - m_PVREnvironmentMIS: 0 + m_PVREnvironmentImportanceSampling: 0 m_PVRFilteringMode: 2 m_PVRDenoiserTypeDirect: 0 m_PVRDenoiserTypeIndirect: 0 @@ -7290,7 +7454,7 @@ LightingSettings: m_PVRFilteringAtrousPositionSigmaDirect: 0.5 m_PVRFilteringAtrousPositionSigmaIndirect: 2 m_PVRFilteringAtrousPositionSigmaAO: 1 - m_PVRTiledBaking: 0 + m_RespectSceneVisibilityWhenBakingGI: 0 --- !u!1 &1572148112 GameObject: m_ObjectHideFlags: 0 @@ -7324,7 +7488,6 @@ RectTransform: m_Children: - {fileID: 1353073342} m_Father: {fileID: 2125002434} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -7457,7 +7620,6 @@ RectTransform: - {fileID: 831307695} - {fileID: 2087928757} m_Father: {fileID: 2125002434} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -7544,7 +7706,6 @@ RectTransform: m_Children: - {fileID: 86597018} m_Father: {fileID: 1396800669} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -7620,7 +7781,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 341355667} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -7703,7 +7863,6 @@ RectTransform: - {fileID: 354744696} - {fileID: 1864455222} m_Father: {fileID: 261595418} - m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -7848,7 +8007,6 @@ RectTransform: m_Children: - {fileID: 606623400} m_Father: {fileID: 2083123983} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -7927,7 +8085,6 @@ RectTransform: - {fileID: 951831624} - {fileID: 535603473} m_Father: {fileID: 1294068891} - m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -8072,7 +8229,6 @@ RectTransform: m_Children: - {fileID: 290153686} m_Father: {fileID: 14215617} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} @@ -8148,7 +8304,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 381735265} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -8227,7 +8382,6 @@ RectTransform: - {fileID: 761227137} - {fileID: 2108742125} m_Father: {fileID: 1294068891} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -8442,7 +8596,6 @@ RectTransform: - {fileID: 911821044} - {fileID: 99782641} m_Father: {fileID: 1294068891} - m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -8518,7 +8671,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2031637684} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -8598,7 +8750,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1653936226} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -8678,7 +8829,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 133447285} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -8800,7 +8950,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1448973720} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -8840,7 +8989,6 @@ RectTransform: m_Children: - {fileID: 1034015604} m_Father: {fileID: 261595418} - m_RootOrder: 6 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -8972,7 +9120,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1045466942} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -9048,7 +9195,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 831307695} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -9126,7 +9272,6 @@ RectTransform: m_Children: - {fileID: 1859021139} m_Father: {fileID: 261595418} - m_RootOrder: 8 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -9259,7 +9404,6 @@ RectTransform: - {fileID: 1699353816} - {fileID: 467055383} m_Father: {fileID: 2125002434} - m_RootOrder: 8 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} @@ -9345,7 +9489,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1597588607} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -9425,7 +9568,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 14215617} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -9505,7 +9647,6 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1795800894} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} @@ -9594,10 +9735,17 @@ RectTransform: - {fileID: 689784487} - {fileID: 1342805839} m_Father: {fileID: 710725585} - m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} m_AnchoredPosition: {x: -9, y: -12} m_SizeDelta: {x: 100, y: 100} m_Pivot: {x: 0.5, y: 0.5} +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 993173863} + - {fileID: 1013663470} + - {fileID: 710725585} + - {fileID: 454893005} diff --git a/unity/ProjectSettings/EditorBuildSettings.asset b/unity/ProjectSettings/EditorBuildSettings.asset index 09be1bb..7cb50b1 100644 --- a/unity/ProjectSettings/EditorBuildSettings.asset +++ b/unity/ProjectSettings/EditorBuildSettings.asset @@ -8,10 +8,14 @@ EditorBuildSettings: - enabled: 0 path: Assets/detectScreen.unity guid: 4f539a39f115d49ff925eae0a5707c57 - - enabled: 1 + - enabled: 0 path: Assets/EmotivUnityPlugin.unity guid: ee5bec8a3b94441e1a701424d4cfc49c - enabled: 0 path: Assets/phone.unity guid: 0bd0ad3adfa0e414abb11fac4b10417e + - enabled: 1 + path: Assets/SimpleExample.unity + guid: d19eaa4b359de7548904eed95b2cd203 m_configObjects: {} + m_UseUCBPForAssetBundles: 0 diff --git a/unity/ProjectSettings/PackageManagerSettings.asset b/unity/ProjectSettings/PackageManagerSettings.asset index 785714b..4f74716 100644 --- a/unity/ProjectSettings/PackageManagerSettings.asset +++ b/unity/ProjectSettings/PackageManagerSettings.asset @@ -13,11 +13,12 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_EnablePreReleasePackages: 0 - m_EnablePackageDependencies: 0 m_AdvancedSettingsExpanded: 1 m_ScopedRegistriesSettingsExpanded: 1 m_SeeAllPackageVersions: 0 + m_DismissPreviewPackagesInUse: 0 oneTimeWarningShown: 0 + oneTimeDeprecatedPopUpShown: 1 m_Registries: - m_Id: main m_Name: @@ -25,11 +26,12 @@ MonoBehaviour: m_Scopes: [] m_IsDefault: 1 m_Capabilities: 7 + m_ConfigSource: 0 m_UserSelectedRegistryName: m_UserAddingNewScopedRegistry: 0 m_RegistryInfoDraft: m_Modified: 0 m_ErrorMessage: - m_UserModificationsInstanceId: -834 - m_OriginalInstanceId: -836 + m_UserModificationsInstanceId: -856 + m_OriginalInstanceId: -858 m_LoadAssets: 0 diff --git a/unity/ProjectSettings/ProjectSettings.asset b/unity/ProjectSettings/ProjectSettings.asset index 3fcfd49..0880b52 100644 --- a/unity/ProjectSettings/ProjectSettings.asset +++ b/unity/ProjectSettings/ProjectSettings.asset @@ -3,7 +3,7 @@ --- !u!129 &1 PlayerSettings: m_ObjectHideFlags: 0 - serializedVersion: 18 + serializedVersion: 27 productGUID: 6036a4feed9bf49558070ac3c2885ad9 AndroidProfiler: 0 AndroidFilterTouchesWhenObscured: 0 @@ -13,7 +13,7 @@ PlayerSettings: useOnDemandResources: 0 accelerometerFrequency: 60 companyName: Emotiv - productName: Emotiv 3D Brain Visualizer v2.4.1 + productName: UnityExample defaultCursor: {fileID: 0} cursorHotspot: {x: 0, y: 0} m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} @@ -48,13 +48,16 @@ PlayerSettings: defaultScreenHeightWeb: 600 m_StereoRenderingPath: 0 m_ActiveColorSpace: 0 + unsupportedMSAAFallback: 0 + m_SpriteBatchVertexThreshold: 300 m_MTRendering: 1 + mipStripping: 0 + numberOfMipsStripped: 0 + numberOfMipsStrippedPerMipmapLimitGroup: {} m_StackTraceTypes: 010000000100000001000000010000000100000001000000 iosShowActivityIndicatorOnLoading: -1 androidShowActivityIndicatorOnLoading: -1 - displayResolutionDialog: 0 iosUseCustomAppBackgroundBehavior: 0 - iosAllowHTTPDownload: 1 allowedAutorotateToPortrait: 0 allowedAutorotateToPortraitUpsideDown: 0 allowedAutorotateToLandscapeRight: 1 @@ -65,7 +68,16 @@ PlayerSettings: disableDepthAndStencilBuffers: 0 androidStartInFullscreen: 1 androidRenderOutsideSafeArea: 0 + androidUseSwappy: 0 androidBlitType: 0 + androidResizableWindow: 1 + androidDefaultWindowWidth: 1920 + androidDefaultWindowHeight: 1080 + androidMinimumWindowWidth: 400 + androidMinimumWindowHeight: 300 + androidFullscreenMode: 1 + androidAutoRotationBehavior: 1 + androidApplicationEntry: 1 defaultIsNativeResolution: 1 macRetinaSupport: 1 runInBackground: 1 @@ -77,13 +89,15 @@ PlayerSettings: hideHomeButton: 0 submitAnalytics: 1 usePlayerLog: 1 + dedicatedServerOptimizations: 0 bakeCollisionMeshes: 0 forceSingleInstance: 0 + useFlipModelSwapchain: 1 resizableWindow: 0 useMacAppStoreValidation: 0 macAppStoreCategory: public.app-category.games gpuSkinning: 0 - graphicsJobs: 0 + meshDeformation: 0 xboxPIXTextureCapture: 0 xboxEnableAvatar: 0 xboxEnableKinect: 0 @@ -91,7 +105,6 @@ PlayerSettings: xboxEnableFitness: 0 visibleInBackground: 0 allowFullscreenSwitch: 1 - graphicsJobMode: 0 fullscreenMode: 1 xboxSpeechDB: 0 xboxEnableHeadOrientation: 0 @@ -112,60 +125,54 @@ PlayerSettings: switchNVNShaderPoolsGranularity: 33554432 switchNVNDefaultPoolsGranularity: 16777216 switchNVNOtherPoolsGranularity: 16777216 + switchGpuScratchPoolGranularity: 2097152 + switchAllowGpuScratchShrinking: 0 + switchNVNMaxPublicTextureIDCount: 0 + switchNVNMaxPublicSamplerIDCount: 0 + switchMaxWorkerMultiple: 8 + switchNVNGraphicsFirmwareMemory: 32 + vulkanNumSwapchainBuffers: 3 vulkanEnableSetSRGBWrite: 0 - m_SupportedAspectRatios: - 4:3: 1 - 5:4: 1 - 16:10: 1 - 16:9: 1 - Others: 1 - bundleVersion: 2.4.1 + vulkanEnablePreTransform: 0 + vulkanEnableLateAcquireNextImage: 0 + vulkanEnableCommandBufferRecycling: 1 + loadStoreDebugModeEnabled: 0 + bundleVersion: 1.1.0 preloadedAssets: [] metroInputSource: 0 wsaTransparentSwapchain: 0 m_HolographicPauseOnTrackingLoss: 1 xboxOneDisableKinectGpuReservation: 0 xboxOneEnable7thCore: 0 - isWsaHolographicRemotingEnabled: 0 vrSettings: - cardboard: - depthFormat: 0 - enableTransitionView: 0 - daydream: - depthFormat: 0 - useSustainedPerformanceMode: 0 - enableVideoLayer: 0 - useProtectedVideoMemory: 0 - minimumSupportedHeadTracking: 0 - maximumSupportedHeadTracking: 1 - hololens: - depthFormat: 1 - depthBufferSharingEnabled: 0 - oculus: - sharedDepthBuffer: 0 - dashSupport: 0 - lowOverheadMode: 0 - protectedContext: 0 - v2Signing: 0 enable360StereoCapture: 0 - protectGraphicsMemory: 0 + isWsaHolographicRemotingEnabled: 0 enableFrameTimingStats: 0 + enableOpenGLProfilerGPURecorders: 1 + allowHDRDisplaySupport: 0 useHDRDisplay: 0 + hdrBitDepth: 0 m_ColorGamuts: 00000000 targetPixelDensity: 30 resolutionScalingMode: 0 + resetResolutionOnWindowResize: 0 androidSupportedAspectRatio: 1 androidMaxAspectRatio: 2.1 + androidMinAspectRatio: 1 applicationIdentifier: - Android: com.emotiv.brainvisualizer + Android: com.emotiv.unityexample Standalone: unity.Emotiv.Emotiv 3D Brain Visualizer v2.4.1 Tizen: com.emotiv.brainvisualizer - iOS: com.emotiv.brainvisualizer + iPhone: com.emotiv.brainvisualizer tvOS: com.emotiv.brainvisualizer buildNumber: - iOS: 0 + Bratwurst: 0 + Standalone: 0 + iPhone: 0 + tvOS: 0 + overrideDefaultApplicationIdentifier: 1 AndroidBundleVersionCode: 13 - AndroidMinSdkVersion: 19 + AndroidMinSdkVersion: 23 AndroidTargetSdkVersion: 0 AndroidPreferredInstallLocation: 1 aotOptions: @@ -175,33 +182,24 @@ PlayerSettings: ForceInternetPermission: 0 ForceSDCardPermission: 0 CreateWallpaper: 0 - APKExpansionFiles: 0 + androidSplitApplicationBinary: 0 keepLoadedShadersAlive: 0 StripUnusedMeshComponents: 0 + strictShaderVariantMatching: 0 VertexChannelCompressionMask: 4054 iPhoneSdkVersion: 988 - iOSTargetOSVersionString: 9.0 + iOSTargetOSVersionString: 13.0 tvOSSdkVersion: 0 tvOSRequireExtendedGameController: 0 - tvOSTargetOSVersionString: 9.0 + tvOSTargetOSVersionString: 13.0 + bratwurstSdkVersion: 0 + bratwurstTargetOSVersionString: 13.0 uIPrerenderedIcon: 0 uIRequiresPersistentWiFi: 1 uIRequiresFullScreen: 1 uIStatusBarHidden: 1 uIExitOnSuspend: 1 uIStatusBarStyle: 0 - iPhoneSplashScreen: {fileID: 0} - iPhoneHighResSplashScreen: {fileID: 0} - iPhoneTallHighResSplashScreen: {fileID: 0} - iPhone47inSplashScreen: {fileID: 0} - iPhone55inPortraitSplashScreen: {fileID: 0} - iPhone55inLandscapeSplashScreen: {fileID: 0} - iPhone58inPortraitSplashScreen: {fileID: 0} - iPhone58inLandscapeSplashScreen: {fileID: 0} - iPadPortraitSplashScreen: {fileID: 0} - iPadHighResPortraitSplashScreen: {fileID: 0} - iPadLandscapeSplashScreen: {fileID: 0} - iPadHighResLandscapeSplashScreen: {fileID: 0} appleTVSplashScreen: {fileID: 0} appleTVSplashScreen2x: {fileID: 0} tvOSSmallIconLayers: [] @@ -229,45 +227,66 @@ PlayerSettings: iOSLaunchScreeniPadFillPct: 100 iOSLaunchScreeniPadSize: 100 iOSLaunchScreeniPadCustomXibPath: - iOSUseLaunchScreenStoryboard: 0 iOSLaunchScreenCustomStoryboardPath: + iOSLaunchScreeniPadCustomStoryboardPath: iOSDeviceRequirements: [] iOSURLSchemes: [] + macOSURLSchemes: [] iOSBackgroundModes: 0 iOSMetalForceHardShadows: 0 metalEditorSupport: 1 metalAPIValidation: 1 iOSRenderExtraFrameOnPause: 1 + iosCopyPluginsCodeInsteadOfSymlink: 0 appleDeveloperTeamID: iOSManualSigningProvisioningProfileID: tvOSManualSigningProvisioningProfileID: + bratwurstManualSigningProvisioningProfileID: iOSManualSigningProvisioningProfileType: 0 tvOSManualSigningProvisioningProfileType: 0 + bratwurstManualSigningProvisioningProfileType: 0 appleEnableAutomaticSigning: 0 iOSRequireARKit: 0 iOSAutomaticallyDetectAndAddCapabilities: 1 appleEnableProMotion: 0 + shaderPrecisionModel: 0 clonedFromGUID: 00000000000000000000000000000000 templatePackageId: templateDefaultScene: - AndroidTargetArchitectures: 5 + useCustomMainManifest: 1 + useCustomLauncherManifest: 0 + useCustomMainGradleTemplate: 1 + useCustomLauncherGradleManifest: 1 + useCustomBaseGradleTemplate: 1 + useCustomGradlePropertiesTemplate: 1 + useCustomGradleSettingsTemplate: 0 + useCustomProguardFile: 0 + AndroidTargetArchitectures: 2 + AndroidTargetDevices: 0 AndroidSplashScreenScale: 0 androidSplashScreen: {fileID: 0} - AndroidKeystoreName: - AndroidKeyaliasName: + AndroidKeystoreName: D:/Saved/unity_android4.keystore + AndroidKeyaliasName: android_key + AndroidEnableArmv9SecurityFeatures: 0 + AndroidEnableArm64MTE: 0 AndroidBuildApkPerCpuArchitecture: 0 AndroidTVCompatibility: 0 AndroidIsGame: 1 AndroidEnableTango: 0 androidEnableBanner: 1 androidUseLowAccuracyLocation: 0 + androidUseCustomKeystore: 1 m_AndroidBanners: - width: 320 height: 180 banner: {fileID: 0} androidGamepadSupportLevel: 0 - resolutionDialogBanner: {fileID: 2800000, guid: 3a69da71d24e78f4caa265a09ccffbe8, - type: 3} + chromeosInputEmulation: 1 + AndroidMinifyRelease: 0 + AndroidMinifyDebug: 0 + AndroidValidateAppBundleSize: 1 + AndroidAppBundleSizeToValidate: 150 + AndroidReportGooglePlayAppDependencies: 1 m_BuildTargetIcons: - m_BuildTarget: m_Icons: @@ -276,16 +295,156 @@ PlayerSettings: m_Width: 128 m_Height: 128 m_Kind: 0 - m_BuildTargetPlatformIcons: [] + m_BuildTargetPlatformIcons: + - m_BuildTarget: Android + m_Icons: + - m_Textures: [] + m_Width: 192 + m_Height: 192 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 144 + m_Height: 144 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 96 + m_Height: 96 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 72 + m_Height: 72 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 48 + m_Height: 48 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 36 + m_Height: 36 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 192 + m_Height: 192 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 144 + m_Height: 144 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 96 + m_Height: 96 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 72 + m_Height: 72 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 48 + m_Height: 48 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 36 + m_Height: 36 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 432 + m_Height: 432 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 324 + m_Height: 324 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 216 + m_Height: 216 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 162 + m_Height: 162 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 108 + m_Height: 108 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 81 + m_Height: 81 + m_Kind: 2 + m_SubKind: m_BuildTargetBatching: [] + m_BuildTargetShaderSettings: [] + m_BuildTargetGraphicsJobs: + - m_BuildTarget: WindowsStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: MacStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: LinuxStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: AndroidPlayer + m_GraphicsJobs: 0 + - m_BuildTarget: iOSSupport + m_GraphicsJobs: 0 + - m_BuildTarget: PS4Player + m_GraphicsJobs: 0 + - m_BuildTarget: PS5Player + m_GraphicsJobs: 0 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobs: 0 + - m_BuildTarget: GameCoreXboxOneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: GameCoreScarlettSupport + m_GraphicsJobs: 0 + - m_BuildTarget: Switch + m_GraphicsJobs: 0 + - m_BuildTarget: WebGLSupport + m_GraphicsJobs: 0 + - m_BuildTarget: MetroSupport + m_GraphicsJobs: 0 + - m_BuildTarget: AppleTVSupport + m_GraphicsJobs: 0 + - m_BuildTarget: BratwurstPlayer + m_GraphicsJobs: 0 + - m_BuildTarget: CloudRendering + m_GraphicsJobs: 0 + - m_BuildTarget: EmbeddedLinux + m_GraphicsJobs: 0 + - m_BuildTarget: QNX + m_GraphicsJobs: 0 + m_BuildTargetGraphicsJobMode: + - m_BuildTarget: PS4Player + m_GraphicsJobMode: 0 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobMode: 0 m_BuildTargetGraphicsAPIs: - m_BuildTarget: AndroidPlayer - m_APIs: 08000000 - m_Automatic: 0 + m_APIs: 150000000b000000 + m_Automatic: 1 + - m_BuildTarget: iOSSupport + m_APIs: 10000000 + m_Automatic: 1 m_BuildTargetVRSettings: [] - m_BuildTargetEnableVuforiaSettings: [] + m_DefaultShaderChunkSizeInMB: 16 + m_DefaultShaderChunkCount: 0 openGLRequireES31: 0 openGLRequireES31AEP: 0 + openGLRequireES32: 0 m_TemplateCustomTags: {} mobileMTRendering: iPhone: 1 @@ -297,7 +456,17 @@ PlayerSettings: m_EncodingQuality: 1 - m_BuildTarget: PS4 m_EncodingQuality: 1 + m_BuildTargetGroupHDRCubemapEncodingQuality: + - m_BuildTarget: Standalone + m_EncodingQuality: 2 + - m_BuildTarget: XboxOne + m_EncodingQuality: 2 + - m_BuildTarget: PS4 + m_EncodingQuality: 2 m_BuildTargetGroupLightmapSettings: [] + m_BuildTargetGroupLoadStoreDebugModeSettings: [] + m_BuildTargetNormalMapEncoding: [] + m_BuildTargetDefaultTextureCompressionFormat: [] playModeTestRunnerEnabled: 0 runPlayModeTestAsEditModeTest: 0 actionOnDotNetUnhandledException: 1 @@ -307,14 +476,20 @@ PlayerSettings: cameraUsageDescription: locationUsageDescription: microphoneUsageDescription: + bluetoothUsageDescription: + macOSTargetOSVersion: 10.13.0 + switchNMETAOverride: switchNetLibKey: switchSocketMemoryPoolSize: 6144 switchSocketAllocatorPoolSize: 128 switchSocketConcurrencyLimit: 14 switchScreenResolutionBehavior: 2 switchUseCPUProfiler: 0 + switchEnableFileSystemTrace: 0 + switchLTOSetting: 0 switchApplicationID: 0x01004b9000490000 switchNSODependencies: + switchCompilerFlags: switchTitleNames_0: switchTitleNames_1: switchTitleNames_2: @@ -330,6 +505,7 @@ PlayerSettings: switchTitleNames_12: switchTitleNames_13: switchTitleNames_14: + switchTitleNames_15: switchPublisherNames_0: switchPublisherNames_1: switchPublisherNames_2: @@ -345,6 +521,7 @@ PlayerSettings: switchPublisherNames_12: switchPublisherNames_13: switchPublisherNames_14: + switchPublisherNames_15: switchIcons_0: {fileID: 0} switchIcons_1: {fileID: 0} switchIcons_2: {fileID: 0} @@ -360,6 +537,7 @@ PlayerSettings: switchIcons_12: {fileID: 0} switchIcons_13: {fileID: 0} switchIcons_14: {fileID: 0} + switchIcons_15: {fileID: 0} switchSmallIcons_0: {fileID: 0} switchSmallIcons_1: {fileID: 0} switchSmallIcons_2: {fileID: 0} @@ -375,6 +553,7 @@ PlayerSettings: switchSmallIcons_12: {fileID: 0} switchSmallIcons_13: {fileID: 0} switchSmallIcons_14: {fileID: 0} + switchSmallIcons_15: {fileID: 0} switchManualHTML: switchAccessibleURLs: switchLegalInformation: @@ -384,7 +563,6 @@ PlayerSettings: switchReleaseVersion: 0 switchDisplayVersion: 1.0.0 switchStartupUserAccount: 0 - switchTouchScreenUsage: 0 switchSupportedLanguagesMask: 0 switchLogoType: 0 switchApplicationErrorCodeCategory: @@ -426,6 +604,7 @@ PlayerSettings: switchNativeFsCacheSize: 32 switchIsHoldTypeHorizontal: 0 switchSupportedNpadCount: 8 + switchEnableTouchScreen: 1 switchSocketConfigEnabled: 0 switchTcpInitialSendBufferSize: 32 switchTcpInitialReceiveBufferSize: 64 @@ -436,7 +615,13 @@ PlayerSettings: switchSocketBufferEfficiency: 4 switchSocketInitializeEnabled: 1 switchNetworkInterfaceManagerInitializeEnabled: 1 - switchPlayerConnectionEnabled: 1 + switchDisableHTCSPlayerConnection: 0 + switchUseNewStyleFilepaths: 1 + switchUseLegacyFmodPriorities: 0 + switchUseMicroSleepForYield: 1 + switchEnableRamDiskSupport: 0 + switchMicroSleepForYieldTime: 25 + switchRamDiskSpaceSize: 12 ps4NPAgeRating: 12 ps4NPTitleSecret: ps4NPTrophyPackPath: @@ -463,6 +648,7 @@ PlayerSettings: ps4ShareFilePath: ps4ShareOverlayImagePath: ps4PrivacyGuardImagePath: + ps4ExtraSceSysFile: ps4NPtitleDatPath: ps4RemotePlayKeyAssignment: -1 ps4RemotePlayKeyMappingDir: @@ -475,6 +661,7 @@ PlayerSettings: ps4DownloadDataSize: 0 ps4GarlicHeapSize: 2048 ps4ProGarlicHeapSize: 2560 + playerPrefsMaxSize: 32768 ps4Passcode: 5xr84P2R391UXaLHbavJvFZGfO47XWS2 ps4pnSessions: 1 ps4pnPresence: 1 @@ -487,6 +674,7 @@ PlayerSettings: ps4UseResolutionFallback: 0 ps4ReprojectionSupport: 0 ps4UseAudio3dBackend: 0 + ps4UseLowGarlicFragmentationMode: 1 ps4SocialScreenEnabled: 0 ps4ScriptOptimizationLevel: 3 ps4Audio3dVirtualSpeakerCount: 14 @@ -503,15 +691,21 @@ PlayerSettings: ps4disableAutoHideSplash: 0 ps4videoRecordingFeaturesUsed: 0 ps4contentSearchFeaturesUsed: 0 + ps4CompatibilityPS5: 0 + ps4AllowPS5Detection: 0 + ps4GPU800MHz: 1 ps4attribEyeToEyeDistanceSettingVR: 0 ps4IncludedModules: [] + ps4attribVROutputEnabled: 0 monoEnv: splashScreenBackgroundSourceLandscape: {fileID: 0} splashScreenBackgroundSourcePortrait: {fileID: 0} + blurSplashScreenBackground: 1 spritePackerPolicy: webGLMemorySize: 256 webGLExceptionSupport: 1 webGLNameFilesAsHashes: 0 + webGLShowDiagnostics: 0 webGLDataCaching: 0 webGLDebugSymbols: 0 webGLEmscriptenArgs: @@ -520,26 +714,61 @@ PlayerSettings: webGLAnalyzeBuildSize: 0 webGLUseEmbeddedResources: 0 webGLCompressionFormat: 1 + webGLWasmArithmeticExceptions: 0 webGLLinkerTarget: 1 webGLThreadsSupport: 0 + webGLDecompressionFallback: 0 + webGLInitialMemorySize: 32 + webGLMaximumMemorySize: 2048 + webGLMemoryGrowthMode: 2 + webGLMemoryLinearGrowthStep: 16 + webGLMemoryGeometricGrowthStep: 0.2 + webGLMemoryGeometricGrowthCap: 96 + webGLEnableWebGPU: 0 + webGLPowerPreference: 2 + webGLWebAssemblyTable: 0 + webGLWebAssemblyBigInt: 0 + webGLCloseOnQuit: 0 scriptingDefineSymbols: {} + additionalCompilerArguments: {} platformArchitecture: - iOS: 0 + iPhone: 1 scriptingBackend: - Android: 0 - Metro: 2 + Android: 1 Standalone: 0 WP8: 2 WebGL: 1 - iOS: 1 + Windows Store Apps: 2 + iPhone: 1 il2cppCompilerConfiguration: {} - managedStrippingLevel: {} + il2cppCodeGeneration: {} + il2cppStacktraceInformation: {} + managedStrippingLevel: + Android: 1 + Bratwurst: 1 + EmbeddedLinux: 1 + GameCoreScarlett: 1 + GameCoreXboxOne: 1 + Nintendo Switch: 1 + PS4: 1 + PS5: 1 + QNX: 1 + WebGL: 1 + Windows Store Apps: 1 + XboxOne: 1 + iPhone: 1 + tvOS: 1 incrementalIl2cppBuild: - iOS: 0 + iPhone: 0 + suppressCommonWarnings: 1 allowUnsafeCode: 0 + useDeterministicCompilation: 1 additionalIl2CppArgs: scriptingRuntimeVersion: 1 + gcIncremental: 1 + gcWBarrierValidation: 0 apiCompatibilityLevelPerPlatform: {} + editorAssembliesCompatibilityLevel: 1 m_RenderingPath: 1 m_MobileRenderingPath: 1 metroPackageName: Brain @@ -563,12 +792,13 @@ PlayerSettings: metroTileBackgroundColor: {r: 0, g: 0, b: 0, a: 1} metroSplashScreenBackgroundColor: {r: 0, g: 0, b: 0, a: 1} metroSplashScreenUseBackgroundColor: 0 + syncCapabilities: 0 platformCapabilities: {} metroTargetDeviceFamilies: {} metroFTAName: metroFTAFileTypes: [] metroProtocolName: - metroCompilationOverrides: 1 + vcxProjDefaultLanguage: XboxOneProductId: XboxOneUpdateKey: XboxOneSandboxId: @@ -587,18 +817,16 @@ PlayerSettings: XboxOneCapability: [] XboxOneGameRating: {} XboxOneIsContentPackage: 0 + XboxOneEnhancedXboxCompatibilityMode: 0 XboxOneEnableGPUVariability: 0 XboxOneSockets: {} XboxOneSplashScreen: {fileID: 0} XboxOneAllowedProductIds: [] XboxOnePersistentLocalStorageSize: 0 XboxOneXTitleMemory: 8 - xboxOneScriptCompiler: 0 XboxOneOverrideIdentityName: - vrEditorSettings: - daydream: - daydreamIconForeground: {fileID: 0} - daydreamIconBackground: {fileID: 0} + XboxOneOverrideIdentityPublisher: + vrEditorSettings: {} cloudServicesEnabled: {} luminIcon: m_Name: @@ -606,24 +834,29 @@ PlayerSettings: m_PortalFolderPath: luminCert: m_CertPath: - m_PrivateKeyPath: + m_SignPackage: 1 luminIsChannelApp: 0 luminVersion: m_VersionCode: 1 m_VersionName: - facebookSdkVersion: 7.9.1 - facebookAppId: - facebookCookies: 1 - facebookLogging: 1 - facebookStatus: 1 - facebookXfbml: 0 - facebookFrictionlessRequests: 1 + hmiPlayerDataPath: + hmiForceSRGBBlit: 0 + embeddedLinuxEnableGamepadInput: 0 + hmiCpuConfiguration: + hmiLogStartupTiming: 0 + qnxGraphicConfPath: apiCompatibilityLevel: 6 + captureStartupLogs: {} + activeInputHandler: 0 + windowsGamepadBackendHint: 0 cloudProjectId: framebufferDepthMemorylessMode: 0 + qualitySettingsNames: [] projectName: organizationId: cloudEnabled: 0 - enableNativePlatformBackendsForNewInputSystem: 0 - disableOldInputManagerSupport: 0 legacyClampBlendShapeWeights: 1 + hmiLoadingImage: {fileID: 0} + platformRequiresReadableAssets: 0 + virtualTexturingSupportEnabled: 0 + insecureHttpOption: 0 diff --git a/unity/ProjectSettings/ProjectVersion.txt b/unity/ProjectSettings/ProjectVersion.txt index 3dcb827..2ffa451 100644 --- a/unity/ProjectSettings/ProjectVersion.txt +++ b/unity/ProjectSettings/ProjectVersion.txt @@ -1,2 +1,2 @@ -m_EditorVersion: 2021.3.2f1 -m_EditorVersionWithRevision: 2021.3.2f1 (d6360bedb9a0) +m_EditorVersion: 2023.2.20f1 +m_EditorVersionWithRevision: 2023.2.20f1 (0e25a174756c) From 525191607be8aace634dceb1e28ee6b478cd3835 Mon Sep 17 00:00:00 2001 From: tung_tung Date: Fri, 22 Nov 2024 17:57:34 +0700 Subject: [PATCH 04/24] add stop and fix textfield issue --- unity/Assets/Plugins/Emotiv-Unity-Plugin | 2 +- unity/Assets/SimpleExample.cs | 79 +++++++++--------------- unity/Assets/SimpleExample.unity | 50 +++++++-------- 3 files changed, 56 insertions(+), 75 deletions(-) diff --git a/unity/Assets/Plugins/Emotiv-Unity-Plugin b/unity/Assets/Plugins/Emotiv-Unity-Plugin index 56aeabd..885f2f8 160000 --- a/unity/Assets/Plugins/Emotiv-Unity-Plugin +++ b/unity/Assets/Plugins/Emotiv-Unity-Plugin @@ -1 +1 @@ -Subproject commit 56aeabd20d2b8a974c5e8a7da558b9c7bde979de +Subproject commit 885f2f871c5e8ff7fd4e2ca857713463e76aa11c diff --git a/unity/Assets/SimpleExample.cs b/unity/Assets/SimpleExample.cs index 8fa8f04..25b232a 100644 --- a/unity/Assets/SimpleExample.cs +++ b/unity/Assets/SimpleExample.cs @@ -10,15 +10,11 @@ #endif public class SimpleExample : MonoBehaviour { - - // Please fill clientId and clientSecret of your application before starting - private string _clientId = ""; - private string _clientSecret = ""; + // Please fill clientId and clientSecret of your application in AppConfig.cs before starting private string _appName = "UnityApp"; private string _appVersion = "3.3.0"; private bool _isStarted = false; - EmotivUnityItf _eItf = EmotivUnityItf.Instance; float _timerDataUpdate = 0; const float TIME_UPDATE_DATA = 1f; @@ -48,32 +44,6 @@ public class SimpleExample : MonoBehaviour // for android #if UNITY_ANDROID - const string pluginName = "com.emotiv.unity.CortexLibManager"; - - private static AndroidJavaClass _pluginClass; - private static AndroidJavaObject _pluginInstance; - private AndroidJavaObject currentActivity; - public static AndroidJavaClass PluginClass - { - get { - if (_pluginClass==null) - { - _pluginClass = new AndroidJavaClass(pluginName); - } - return _pluginClass; - } - } - - public static AndroidJavaObject PluginInstance - { - get { - if (_pluginInstance==null) - { - _pluginInstance = PluginClass.CallStatic("getInstance"); - } - return _pluginInstance; - } - } private const string FineLocationPermission = "android.permission.ACCESS_FINE_LOCATION"; private const string BluetoothScanPermission = "android.permission.BLUETOOTH_SCAN"; private const string BluetoothConnectPermission = "android.permission.BLUETOOTH_CONNECT"; @@ -101,7 +71,7 @@ private bool HasAllPermissions() IEnumerator RequestPermissions() { - yield return new WaitForSeconds(1f); // Wait for a second to ensure the app is fully initialized + yield return new WaitForSeconds(1f); if (!HasPermission(FineLocationPermission)) { @@ -123,6 +93,18 @@ IEnumerator RequestPermissions() } } + // start EmotivUnityItf for android + private void StartEmotivUnityItfForAndroid() { + if (HasAllPermissions()) { + AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); + _eItf.Start(unityPlayer.GetStatic("currentActivity")); + _isStarted = true; + } + else if (!HasAllPermissions()) { + StartCoroutine(RequestPermissions()); + } + } + private static bool HasPermission(string permissionName) { return Permission.HasUserAuthorizedPermission(permissionName); @@ -144,14 +126,21 @@ private static void RequestPermission(string permissionName) { void Start() { + if (_isStarted) + return; + // init EmotivUnityItf without data buffer using _eItf.Init(AppConfig.ClientId, AppConfig.ClientSecret, _appName, _appVersion, AppConfig.UserName, AppConfig.Password, _isDataBufferUsing); - - #if !UNITY_ANDROID && !UNITY_IOS - UnityEngine.Debug.Log("SimpleExp: Start EmotivUnityItf for test"); - _eItf.Start(); + + #if UNITY_ANDROID + StartEmotivUnityItfForAndroid(); + # elif UNITY_IOS + UnityEngine.Debug.Log("SimpleExp: Start EmotivUnityItf for ios"); + #else + UnityEngine.Debug.Log("SimpleExp: Start EmotivUnityItf for desktop"); + _eItf.Start(); + _isStarted = true; #endif - } // Update is called once per frame @@ -173,16 +162,9 @@ void Update() MessageLog.text = _eItf.MessageLog; #if UNITY_ANDROID - if (HasAllPermissions() && !_isStarted) { - AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); - // Get the current activity - currentActivity = unityPlayer.GetStatic("currentActivity"); - _eItf.Start(currentActivity); - - _isStarted = true; - } - else if (!_isStarted) { - StartCoroutine(RequestPermissions()); + // check all permissions are granted + if (!_isStarted) { + StartEmotivUnityItfForAndroid(); } #endif @@ -191,8 +173,7 @@ void Update() // Check to call scan headset if no session is created and no scanning headset if (!_eItf.IsSessionCreated && !DataStreamManager.Instance.IsHeadsetScanning) { - // UnityEngine.Debug.Log("qqqqqqq SimpleExp: No scanning headset"); - // Start scanning headset at headset list screen + // TODO :Start scanning headset at headset list screen // DataStreamManager.Instance.ScanHeadsets(); } diff --git a/unity/Assets/SimpleExample.unity b/unity/Assets/SimpleExample.unity index e596995..4a9bb84 100644 --- a/unity/Assets/SimpleExample.unity +++ b/unity/Assets/SimpleExample.unity @@ -435,8 +435,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 201.48, y: 138} - m_SizeDelta: {x: 162.65, y: 33} + m_AnchoredPosition: {x: 206.91, y: 138.75} + m_SizeDelta: {x: 173.51, y: 31.5} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &85301052 MonoBehaviour: @@ -681,7 +681,7 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 16 m_FontStyle: 0 - m_BestFit: 0 + m_BestFit: 1 m_MinSize: 1 m_MaxSize: 40 m_Alignment: 0 @@ -897,7 +897,7 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 16 m_FontStyle: 1 - m_BestFit: 0 + m_BestFit: 1 m_MinSize: 1 m_MaxSize: 40 m_Alignment: 3 @@ -1025,7 +1025,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_Color: {r: 0.084905684, g: 0.00040049947, b: 0.00040049947, a: 0.5} m_RaycastTarget: 1 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 @@ -1036,7 +1036,7 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 16 m_FontStyle: 2 - m_BestFit: 0 + m_BestFit: 1 m_MinSize: 1 m_MaxSize: 40 m_Alignment: 0 @@ -1553,8 +1553,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 9.1656, y: -0.5} - m_SizeDelta: {x: -1.6687, y: -13} + m_AnchoredPosition: {x: 2.4438, y: -0.5} + m_SizeDelta: {x: -10.9812, y: -13} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &354744697 MonoBehaviour: @@ -1580,9 +1580,9 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 16 m_FontStyle: 2 - m_BestFit: 0 + m_BestFit: 1 m_MinSize: 1 - m_MaxSize: 40 + m_MaxSize: 20 m_Alignment: 0 m_AlignByGeometry: 0 m_RichText: 1 @@ -2033,7 +2033,7 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 16 m_FontStyle: 0 - m_BestFit: 0 + m_BestFit: 1 m_MinSize: 1 m_MaxSize: 40 m_Alignment: 0 @@ -2337,7 +2337,7 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 16 m_FontStyle: 1 - m_BestFit: 0 + m_BestFit: 1 m_MinSize: 1 m_MaxSize: 40 m_Alignment: 3 @@ -2800,7 +2800,7 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 16 m_FontStyle: 2 - m_BestFit: 0 + m_BestFit: 1 m_MinSize: 1 m_MaxSize: 40 m_Alignment: 0 @@ -3729,7 +3729,7 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 16 m_FontStyle: 2 - m_BestFit: 0 + m_BestFit: 1 m_MinSize: 1 m_MaxSize: 40 m_Alignment: 0 @@ -3985,7 +3985,7 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 16 m_FontStyle: 2 - m_BestFit: 0 + m_BestFit: 1 m_MinSize: 1 m_MaxSize: 40 m_Alignment: 0 @@ -5558,7 +5558,7 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 16 m_FontStyle: 0 - m_BestFit: 0 + m_BestFit: 1 m_MinSize: 1 m_MaxSize: 40 m_Alignment: 0 @@ -7162,7 +7162,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_Color: {r: 0.09433961, g: 0.00756497, b: 0.00756497, a: 1} m_RaycastTarget: 1 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 @@ -7173,7 +7173,7 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 16 m_FontStyle: 0 - m_BestFit: 0 + m_BestFit: 1 m_MinSize: 1 m_MaxSize: 40 m_Alignment: 0 @@ -7866,8 +7866,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 201.47481, y: 187.45001} - m_SizeDelta: {x: 162.65, y: 33} + m_AnchoredPosition: {x: 206.90714, y: 187.44998} + m_SizeDelta: {x: 173.5147, y: 33} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &1653936227 MonoBehaviour: @@ -8753,8 +8753,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: -0.5} - m_SizeDelta: {x: -20, y: -13} + m_AnchoredPosition: {x: -1.0090027, y: -0.5} + m_SizeDelta: {x: -8.618, y: -13} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &1864455223 MonoBehaviour: @@ -8780,7 +8780,7 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 16 m_FontStyle: 0 - m_BestFit: 0 + m_BestFit: 1 m_MinSize: 1 m_MaxSize: 40 m_Alignment: 0 @@ -8919,7 +8919,7 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 16 m_FontStyle: 2 - m_BestFit: 0 + m_BestFit: 1 m_MinSize: 1 m_MaxSize: 40 m_Alignment: 0 @@ -9677,7 +9677,7 @@ MonoBehaviour: m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} m_FontSize: 16 m_FontStyle: 0 - m_BestFit: 0 + m_BestFit: 1 m_MinSize: 1 m_MaxSize: 40 m_Alignment: 0 From b81c76f764be3c7f2ba5a9111e4570e4214a4333 Mon Sep 17 00:00:00 2001 From: tung_tung Date: Tue, 3 Dec 2024 11:17:54 +0700 Subject: [PATCH 05/24] remove doTween package --- unity/Assets/Demigiant/DOTween.meta | 8 - unity/Assets/Demigiant/DOTween/DOTween.XML | 2963 ----------------- .../Assets/Demigiant/DOTween/DOTween.XML.meta | 4 - unity/Assets/Demigiant/DOTween/DOTween.dll | Bin 172032 -> 0 bytes .../Assets/Demigiant/DOTween/DOTween.dll.mdb | Bin 66532 -> 0 bytes .../Demigiant/DOTween/DOTween.dll.mdb.meta | 4 - .../Assets/Demigiant/DOTween/DOTween.dll.meta | 22 - unity/Assets/Demigiant/DOTween/Editor.meta | 5 - .../DOTween/Editor/DOTweenEditor.XML | 110 - .../DOTween/Editor/DOTweenEditor.XML.meta | 4 - .../DOTween/Editor/DOTweenEditor.dll | Bin 66048 -> 0 bytes .../DOTween/Editor/DOTweenEditor.dll.mdb | Bin 11774 -> 0 bytes .../DOTween/Editor/DOTweenEditor.dll.mdb.meta | 4 - .../DOTween/Editor/DOTweenEditor.dll.meta | 22 - .../Assets/Demigiant/DOTween/Editor/Imgs.meta | 5 - .../DOTween/Editor/Imgs/DOTweenIcon.png | Bin 1565 -> 0 bytes .../DOTween/Editor/Imgs/DOTweenIcon.png.meta | 47 - .../DOTween/Editor/Imgs/DOTweenMiniIcon.png | Bin 319 -> 0 bytes .../Editor/Imgs/DOTweenMiniIcon.png.meta | 68 - .../Demigiant/DOTween/Editor/Imgs/Footer.png | Bin 4409 -> 0 bytes .../DOTween/Editor/Imgs/Footer.png.meta | 47 - .../DOTween/Editor/Imgs/Footer_dark.png | Bin 4429 -> 0 bytes .../DOTween/Editor/Imgs/Footer_dark.png.meta | 47 - .../Demigiant/DOTween/Editor/Imgs/Header.jpg | Bin 22787 -> 0 bytes .../DOTween/Editor/Imgs/Header.jpg.meta | 47 - unity/Assets/Demigiant/DOTween/Modules.meta | 5 - .../DOTween/Modules/DOTweenModuleAudio.cs | 202 -- .../Modules/DOTweenModuleAudio.cs.meta | 8 - .../Modules/DOTweenModuleEPOOutline.cs | 142 - .../Modules/DOTweenModuleEPOOutline.cs.meta | 12 - .../DOTween/Modules/DOTweenModulePhysics.cs | 216 -- .../Modules/DOTweenModulePhysics.cs.meta | 8 - .../DOTween/Modules/DOTweenModulePhysics2D.cs | 193 -- .../Modules/DOTweenModulePhysics2D.cs.meta | 8 - .../DOTween/Modules/DOTweenModuleSprite.cs | 93 - .../Modules/DOTweenModuleSprite.cs.meta | 8 - .../DOTween/Modules/DOTweenModuleUI.cs | 660 ---- .../DOTween/Modules/DOTweenModuleUI.cs.meta | 8 - .../Modules/DOTweenModuleUnityVersion.cs | 403 --- .../Modules/DOTweenModuleUnityVersion.cs.meta | 8 - .../DOTween/Modules/DOTweenModuleUtils.cs | 167 - .../Modules/DOTweenModuleUtils.cs.meta | 8 - unity/Assets/Demigiant/DOTween/readme.txt | 29 - .../Assets/Demigiant/DOTween/readme.txt.meta | 4 - .../script/Controller/BaseCanvasView.cs | 65 +- .../ConnectHeadsetController.cs | 5 +- unity/ProjectSettings/ProjectSettings.asset | 4 +- .../UnityConnectSettings.asset | 2 + 48 files changed, 41 insertions(+), 5624 deletions(-) delete mode 100644 unity/Assets/Demigiant/DOTween.meta delete mode 100644 unity/Assets/Demigiant/DOTween/DOTween.XML delete mode 100644 unity/Assets/Demigiant/DOTween/DOTween.XML.meta delete mode 100644 unity/Assets/Demigiant/DOTween/DOTween.dll delete mode 100644 unity/Assets/Demigiant/DOTween/DOTween.dll.mdb delete mode 100644 unity/Assets/Demigiant/DOTween/DOTween.dll.mdb.meta delete mode 100644 unity/Assets/Demigiant/DOTween/DOTween.dll.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Editor.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.XML delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.XML.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll.mdb delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll.mdb.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/Imgs.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/Imgs/DOTweenIcon.png delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/Imgs/DOTweenIcon.png.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/Imgs/DOTweenMiniIcon.png delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/Imgs/DOTweenMiniIcon.png.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/Imgs/Footer.png delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/Imgs/Footer.png.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/Imgs/Footer_dark.png delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/Imgs/Footer_dark.png.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/Imgs/Header.jpg delete mode 100644 unity/Assets/Demigiant/DOTween/Editor/Imgs/Header.jpg.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Modules.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleAudio.cs delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleAudio.cs.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleEPOOutline.cs delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleEPOOutline.cs.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics.cs delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics.cs.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics2D.cs delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics2D.cs.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleSprite.cs delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleSprite.cs.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUI.cs delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUI.cs.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUnityVersion.cs delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUnityVersion.cs.meta delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUtils.cs delete mode 100644 unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUtils.cs.meta delete mode 100644 unity/Assets/Demigiant/DOTween/readme.txt delete mode 100644 unity/Assets/Demigiant/DOTween/readme.txt.meta diff --git a/unity/Assets/Demigiant/DOTween.meta b/unity/Assets/Demigiant/DOTween.meta deleted file mode 100644 index fdb7467..0000000 --- a/unity/Assets/Demigiant/DOTween.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 41908594ce4578644a41608ee384b39b -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/unity/Assets/Demigiant/DOTween/DOTween.XML b/unity/Assets/Demigiant/DOTween/DOTween.XML deleted file mode 100644 index 762220e..0000000 --- a/unity/Assets/Demigiant/DOTween/DOTween.XML +++ /dev/null @@ -1,2963 +0,0 @@ - - - - DOTween - - - - - Types of autoPlay behaviours - - - - No tween is automatically played - - - Only Sequences are automatically played - - - Only Tweeners are automatically played - - - All tweens are automatically played - - - - What axis to constrain in case of Vector tweens - - - - Called the first time the tween is set in a playing state, after any eventual delay - - - - Used in place of System.Func, which is not available in mscorlib. - - - - - Used in place of System.Action. - - - - - Public so it can be used by lose scripts related to DOTween (like DOTweenAnimation) - - - - - Used to separate DOTween class from the MonoBehaviour instance (in order to use static constructors on DOTween). - Contains all instance-based methods - - - - Used internally inside Unity Editor, as a trick to update DOTween's inspector at every frame - - - - Directly sets the current max capacity of Tweeners and Sequences - (meaning how many Tweeners and Sequences can be running at the same time), - so that DOTween doesn't need to automatically increase them in case the max is reached - (which might lead to hiccups when that happens). - Sequences capacity must be less or equal to Tweeners capacity - (if you pass a low Tweener capacity it will be automatically increased to match the Sequence's). - Beware: use this method only when there are no tweens running. - - Max Tweeners capacity. - Default: 200 - Max Sequences capacity. - Default: 50 - - - - This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing). - - - - - Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in: accelerating from zero velocity. - - - Current time (in frames or seconds). - - - Expected easing duration (in frames or seconds). - - Unused: here to keep same delegate for all ease types. - Unused: here to keep same delegate for all ease types. - - The eased value. - - - - - Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out: decelerating from zero velocity. - - - Current time (in frames or seconds). - - - Expected easing duration (in frames or seconds). - - Unused: here to keep same delegate for all ease types. - Unused: here to keep same delegate for all ease types. - - The eased value. - - - - - Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in/out: acceleration until halfway, then deceleration. - - - Current time (in frames or seconds). - - - Expected easing duration (in frames or seconds). - - Unused: here to keep same delegate for all ease types. - Unused: here to keep same delegate for all ease types. - - The eased value. - - - - - Returns a value between 0 and 1 (inclusive) based on the elapsed time and ease selected - - - - - Returns a value between 0 and 1 (inclusive) based on the elapsed time and ease selected - - - - - Used to interpret AnimationCurves as eases. - Public so it can be used by external ease factories - - - - - Behaviour in case a tween nested inside a Sequence fails and is captured by safe mode - - - - If the Sequence contains other elements, kill the failed tween but preserve the rest - - - Kill the whole Sequence - - - - Log types thrown by errors captured and prevented by safe mode - - - - No logs. NOT RECOMMENDED - - - Throw a normal log - - - Throw a warning log (default) - - - Throw an error log - - - - Additional notices passed to plugins when updating. - Public so it can be used by custom plugins. Internally, only PathPlugin uses it - - - - - None - - - - - Lets the plugin know that we restarted or rewinded - - - - - OnRewind callback behaviour (can only be set via DOTween's Utility Panel) - - - - - When calling Rewind or PlayBackwards/SmoothRewind, OnRewind callbacks will be fired only if the tween isn't already rewinded - - - - - When calling Rewind, OnRewind callbacks will always be fired, even if the tween is already rewinded. - When calling PlayBackwards/SmoothRewind instead, OnRewind callbacks will be fired only if the tween isn't already rewinded - - - - - When calling Rewind or PlayBackwards/SmoothRewind, OnRewind callbacks will always be fired, even if the tween is already rewinded - - - - - Public only so custom shortcuts can access some of these methods - - - - - INTERNAL: used by DO shortcuts and Modules to set special startup mode - - - - - INTERNAL: used by DO shortcuts and Modules to set the tween as blendable - - - - - INTERNAL: used by DO shortcuts and Modules to prevent a tween from using a From setup even if passed - - - - - Used to dispatch commands that need to be captured externally, usually by Modules - - - - - Returns a Vector3 with z = 0 - - - - - Returns the 2D angle between two vectors - - - - - Returns a point on a circle with the given center and radius, - using Unity's circle coordinates (0° points up and increases clockwise) - - - - - Uses approximate equality on each axis instead of Unity's Vector3 equality, - because the latter fails (in some cases) when assigning a Vector3 to a transform.position and then checking it. - - - - - Looks for the type within all possible project assembly names - - - - NO-GC METHOD: changes the start value of a tween and rewinds it (without pausing it). - Has no effect with tweens that are inside Sequences - The new start value - If bigger than 0 applies it as the new tween duration - - - NO-GC METHOD: changes the end value of a tween and rewinds it (without pausing it). - Has no effect with tweens that are inside Sequences - The new end value - If TRUE the start value will become the current target's value, otherwise it will stay the same - - - NO-GC METHOD: changes the end value of a tween and rewinds it (without pausing it). - Has no effect with tweens that are inside Sequences - The new end value - If bigger than 0 applies it as the new tween duration - If TRUE the start value will become the current target's value, otherwise it will stay the same - - - NO-GC METHOD: changes the start and end value of a tween and rewinds it (without pausing it). - Has no effect with tweens that are inside Sequences - The new start value - The new end value - If bigger than 0 applies it as the new tween duration - - - - Struct that stores two colors (used for LineRenderer tweens) - - - - - Used for tween callbacks - - - - - Used for tween callbacks - - - - - Used for custom and animationCurve-based ease functions. Must return a value between 0 and 1. - - - - - Straight Quaternion plugin. Instead of using Vector3 values accepts Quaternion values directly. - Beware: doesn't work with LoopType.Incremental (neither directly nor if inside a LoopType.Incremental Sequence). - To use it, call DOTween.To with the plugin parameter overload, passing it PureQuaternionPlugin.Plug() as first parameter - (do not use any of the other public PureQuaternionPlugin methods): - DOTween.To(PureQuaternionPlugin.Plug(), ()=> myQuaternionProperty, x=> myQuaternionProperty = x, myQuaternionEndValue, duration); - - - - - Plug this plugin inside a DOTween.To call. - Example: - DOTween.To(PureQuaternionPlugin.Plug(), ()=> myQuaternionProperty, x=> myQuaternionProperty = x, myQuaternionEndValue, duration); - - - - INTERNAL: do not use - - - INTERNAL: do not use - - - INTERNAL: do not use - - - INTERNAL: do not use - - - INTERNAL: do not use - - - INTERNAL: do not use - - - INTERNAL: do not use - - - INTERNAL: do not use - - - - Extra non-tweening-related curve methods - - - - - Cubic bezier curve methods - - - - - Calculates a point along the given Cubic Bezier segment-curve. - - Segment start point - Start point's control point/handle - Segment end point - End point's control point/handle - 0-1 percentage along which to retrieve point - - - - Returns an array containing a series of points along the given Cubic Bezier segment-curve. - - Start point - Start point's control point/handle - End point - End point's control point/handle - Cloud resolution (min: 2) - - - - Calculates a series of points along the given Cubic Bezier segment-curve and adds them to the given list. - - Start point - Start point's control point/handle - End point - End point's control point/handle - Cloud resolution (min: 2) - - - - Main DOTween class. Contains static methods to create and control tweens in a generic way - - - - DOTween's version - - - If TRUE (default) makes tweens slightly slower but safer, automatically taking care of a series of things - (like targets becoming null while a tween is playing). - Default: TRUE - - - Log type when safe mode reports capturing an error and preventing it - - - Behaviour in case a tween nested inside a Sequence fails (and is caught by safe mode). - Default: NestedTweenFailureBehaviour.TryToPreserveSequence - - - If TRUE you will get a DOTween report when exiting play mode (only in the Editor). - Useful to know how many max Tweeners and Sequences you reached and optimize your final project accordingly. - Beware, this will slightly slow down your tweens while inside Unity Editor. - Default: FALSE - - - Global DOTween timeScale. - Default: 1 - - - If TRUE, DOTween will use Time.smoothDeltaTime instead of Time.deltaTime for UpdateType.Normal and UpdateType.Late tweens - (unless they're set as timeScaleIndependent, in which case a value between the last timestep - and will be used instead). - Setting this to TRUE will lead to smoother animations. - Default: FALSE - - - If is TRUE, this indicates the max timeStep that an independent update call can last. - Setting this to TRUE will lead to smoother animations. - Default: FALSE - - - DOTween's log behaviour. - Default: LogBehaviour.ErrorsOnly - - - Used to intercept DOTween's logs. If this method isn't NULL, DOTween will call it before writing a log via Unity's own Debug log methods. - Return TRUE if you want DOTween to proceed with the log, FALSE otherwise. - This method must return a bool and accept two parameters: - - LogType: the type of Unity log that DOTween is trying to log - - object: the log message that DOTween wants to log - - - If TRUE draws path gizmos in Unity Editor (if the gizmos button is active). - Deactivate this if you want to avoid gizmos overhead while in Unity Editor - - - If TRUE activates various debug options - - - Stores the target id so it can be used to give more info in case of safeMode error capturing. - Only active if both debugMode and useSafeMode are TRUE - - - Default updateType for new tweens. - Default: UpdateType.Normal - - - Sets whether Unity's timeScale should be taken into account by default or not. - Default: false - - - Default autoPlay behaviour for new tweens. - Default: AutoPlay.All - - - Default autoKillOnComplete behaviour for new tweens. - Default: TRUE - - - Default loopType applied to all new tweens. - Default: LoopType.Restart - - - If TRUE all newly created tweens are set as recyclable, otherwise not. - Default: FALSE - - - Default ease applied to all new Tweeners (not to Sequences which always have Ease.Linear as default). - Default: Ease.InOutQuad - - - Default overshoot/amplitude used for eases - Default: 1.70158f - - - Default period used for eases - Default: 0 - - - Used internally. Assigned/removed by DOTweenComponent.Create/DestroyInstance - - - - Must be called once, before the first ever DOTween call/reference, - otherwise it will be called automatically and will use default options. - Calling it a second time won't have any effect. - You can chain SetCapacity to this method, to directly set the max starting size of Tweeners and Sequences: - DOTween.Init(false, false, LogBehaviour.Default).SetCapacity(100, 20); - - If TRUE all new tweens will be set for recycling, meaning that when killed, - instead of being destroyed, they will be put in a pool and reused instead of creating new tweens. This option allows you to avoid - GC allocations by reusing tweens, but you will have to take care of tween references, since they might result active - even if they were killed (since they might have been respawned and are now being used for other tweens). - If you want to automatically set your tween references to NULL when a tween is killed - you can use the OnKill callback like this: - .OnKill(()=> myTweenReference = null) - You can change this setting at any time by changing the static property, - or you can set the recycling behaviour for each tween separately, using: - SetRecyclable(bool recyclable) - Default: FALSE - If TRUE makes tweens slightly slower but safer, automatically taking care of a series of things - (like targets becoming null while a tween is playing). - You can change this setting at any time by changing the static property. - Default: FALSE - Type of logging to use. - You can change this setting at any time by changing the static property. - Default: ErrorsOnly - - - - Directly sets the current max capacity of Tweeners and Sequences - (meaning how many Tweeners and Sequences can be running at the same time), - so that DOTween doesn't need to automatically increase them in case the max is reached - (which might lead to hiccups when that happens). - Sequences capacity must be less or equal to Tweeners capacity - (if you pass a low Tweener capacity it will be automatically increased to match the Sequence's). - Beware: use this method only when there are no tweens running. - - Max Tweeners capacity. - Default: 200 - Max Sequences capacity. - Default: 50 - - - - Kills all tweens, clears all cached tween pools and plugins and resets the max Tweeners/Sequences capacities to the default values. - - If TRUE also destroys DOTween's gameObject and resets its initializiation, default settings and everything else - (so that next time you use it it will need to be re-initialized) - - - - Clears all cached tween pools. - - - - - Checks all active tweens to find and remove eventually invalid ones (usually because their targets became NULL) - and returns the total number of invalid tweens found and removed. - IMPORTANT: this will cause an error on UWP platform, so don't use it there - BEWARE: this is a slightly expensive operation so use it with care - - - - - Updates all tweens that are set to . - - Manual deltaTime - Unscaled delta time (used with tweens set as timeScaleIndependent) - - - Tweens a property or field to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a property or field to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a property or field to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a property or field to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a property or field to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a property or field to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a property or field to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a property or field to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a property or field to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a property or field to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a property or field to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a property or field to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a property or field to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a property or field to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a property or field to the given value using a custom plugin - The plugin to use. Each custom plugin implements a static Get() method - you'll need to call to assign the correct plugin in the correct way, like this: - CustomPlugin.Get() - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens only one axis of a Vector3 to the given value using default plugins. - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - The axis to tween - - - Tweens only the alpha of a Color to the given value using default plugins - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end value to reachThe tween's duration - - - Tweens a virtual property from the given start to the given end value - and implements a setter that allows to use that value with an external method or a lambda - Example: - To(MyMethod, 0, 12, 0.5f); - Where MyMethod is a function that accepts a float parameter (which will be the result of the virtual tween) - The action to perform with the tweened value - The value to start from - The end value to reach - The duration of the virtual tween - - - - Punches a Vector3 towards the given direction and then back to the starting one - as if it was connected to the starting position via an elastic. - This tween type generates some GC allocations at startup - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The direction and strength of the punch - The duration of the tween - Indicates how much will the punch vibrate - Represents how much (0 to 1) the vector will go beyond the starting position when bouncing backwards. - 1 creates a full oscillation between the direction and the opposite decaying direction, - while 0 oscillates only between the starting position and the decaying direction - - - Shakes a Vector3 with the given values. - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The duration of the tween - The shake strength - Indicates how much will the shake vibrate - Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). - Setting it to 0 will shake along a single direction and behave like a random punch. - If TRUE only shakes on the X Y axis (looks better with things like cameras). - If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not - - - Shakes a Vector3 with the given values. - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The duration of the tween - The shake strength on each axis - Indicates how much will the shake vibrate - Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). - Setting it to 0 will shake along a single direction and behave like a random punch. - If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not - - - Tweens a property or field to the given values using default plugins. - Ease is applied between each segment and not as a whole. - This tween type generates some GC allocations at startup - A getter for the field or property to tween. - Example usage with lambda:()=> myProperty - A setter for the field or property to tween - Example usage with lambda:x=> myProperty = x - The end values to reach for each segment. This array must have the same length as durations - The duration of each segment. This array must have the same length as endValues - - - - Returns a new to be used for tween groups. - Mind that Sequences don't have a target applied automatically like Tweener creation shortcuts, - so if you want to be able to kill this Sequence when calling DOTween.Kill(target) you'll have to add - the target manually; you can do that directly by using the overload instead of this one - - - - - Returns a new to be used for tween groups, and allows to set a target - (because Sequences don't have their target set automatically like Tweener creation shortcuts). - That way killing/controlling tweens by target will apply to this Sequence too. - - The target of the Sequence. Relevant only for static target-based methods like DOTween.Kill(target), - useless otherwise - - - Completes all tweens and returns the number of actual tweens completed - (meaning tweens that don't have infinite loops and were not already complete) - For Sequences only: if TRUE also internal Sequence callbacks will be fired, - otherwise they will be ignored - - - Completes all tweens with the given ID or target and returns the number of actual tweens completed - (meaning the tweens that don't have infinite loops and were not already complete) - For Sequences only: if TRUE internal Sequence callbacks will be fired, - otherwise they will be ignored - - - Flips all tweens (changing their direction to forward if it was backwards and viceversa), - then returns the number of actual tweens flipped - - - Flips the tweens with the given ID or target (changing their direction to forward if it was backwards and viceversa), - then returns the number of actual tweens flipped - - - Sends all tweens to the given position (calculating also eventual loop cycles) and returns the actual tweens involved - - - Sends all tweens with the given ID or target to the given position (calculating also eventual loop cycles) - and returns the actual tweens involved - - - Kills all tweens and returns the number of actual tweens killed - If TRUE completes the tweens before killing them - - - Kills all tweens and returns the number of actual tweens killed - If TRUE completes the tweens before killing them - Eventual IDs or targets to exclude from the killing - - - Kills all tweens with the given ID or target and returns the number of actual tweens killed - If TRUE completes the tweens before killing them - - - Kills all tweens with the given target and the given ID, and returns the number of actual tweens killed - If TRUE completes the tweens before killing them - - - Pauses all tweens and returns the number of actual tweens paused - - - Pauses all tweens with the given ID or target and returns the number of actual tweens paused - (meaning the tweens that were actually playing and have been paused) - - - Plays all tweens and returns the number of actual tweens played - (meaning tweens that were not already playing or complete) - - - Plays all tweens with the given ID or target and returns the number of actual tweens played - (meaning the tweens that were not already playing or complete) - - - Plays all tweens with the given target and the given ID, and returns the number of actual tweens played - (meaning the tweens that were not already playing or complete) - - - Plays backwards all tweens and returns the number of actual tweens played - (meaning tweens that were not already started, playing backwards or rewinded) - - - Plays backwards all tweens with the given ID or target and returns the number of actual tweens played - (meaning the tweens that were not already started, playing backwards or rewinded) - - - Plays backwards all tweens with the given target and ID and returns the number of actual tweens played - (meaning the tweens that were not already started, playing backwards or rewinded) - - - Plays forward all tweens and returns the number of actual tweens played - (meaning tweens that were not already playing forward or complete) - - - Plays forward all tweens with the given ID or target and returns the number of actual tweens played - (meaning the tweens that were not already playing forward or complete) - - - Plays forward all tweens with the given target and ID and returns the number of actual tweens played - (meaning the tweens that were not already started, playing backwards or rewinded) - - - Restarts all tweens, then returns the number of actual tweens restarted - - - Restarts all tweens with the given ID or target, then returns the number of actual tweens restarted - If TRUE includes the eventual tweens delays, otherwise skips them - If >= 0 changes the startup delay of all involved tweens to this value, otherwise doesn't touch it - - - Restarts all tweens with the given target and the given ID, and returns the number of actual tweens played - (meaning the tweens that were not already playing or complete) - If TRUE includes the eventual tweens delays, otherwise skips them - If >= 0 changes the startup delay of all involved tweens to this value, otherwise doesn't touch it - - - Rewinds and pauses all tweens, then returns the number of actual tweens rewinded - (meaning tweens that were not already rewinded) - - - Rewinds and pauses all tweens with the given ID or target, then returns the number of actual tweens rewinded - (meaning the tweens that were not already rewinded) - - - Smoothly rewinds all tweens (delays excluded), then returns the number of actual tweens rewinding/rewinded - (meaning tweens that were not already rewinded). - A "smooth rewind" animates the tween to its start position, - skipping all elapsed loops (except in case of LoopType.Incremental) while keeping the animation fluent. - Note that a tween that was smoothly rewinded will have its play direction flipped - - - Smoothly rewinds all tweens (delays excluded) with the given ID or target, then returns the number of actual tweens rewinding/rewinded - (meaning the tweens that were not already rewinded). - A "smooth rewind" animates the tween to its start position, - skipping all elapsed loops (except in case of LoopType.Incremental) while keeping the animation fluent. - Note that a tween that was smoothly rewinded will have its play direction flipped - - - Toggles the play state of all tweens and returns the number of actual tweens toggled - (meaning tweens that could be played or paused, depending on the toggle state) - - - Toggles the play state of all tweens with the given ID or target and returns the number of actual tweens toggled - (meaning the tweens that could be played or paused, depending on the toggle state) - - - - Returns TRUE if a tween with the given ID or target is active. - You can also use this to know if a shortcut tween is active for a given target. - Example: - transform.DOMoveX(45, 1); // transform is automatically added as the tween target - DOTween.IsTweening(transform); // Returns true - - The target or ID to look for - If FALSE (default) returns TRUE as long as a tween for the given target/ID is active, - otherwise also requires it to be playing - - - - Returns the total number of active tweens. - A tween is considered active if it wasn't killed, regardless if it's playing or paused - - - - - Returns the total number of active and playing tweens. - A tween is considered as playing even if its delay is actually playing - - - - - Returns a list of all active tweens in a playing state. - Returns NULL if there are no active playing tweens. - Beware: each time you call this method a new list is generated, so use it for debug only - - If NULL creates a new list, otherwise clears and fills this one (and thus saves allocations) - - - - Returns a list of all active tweens in a paused state. - Returns NULL if there are no active paused tweens. - Beware: each time you call this method a new list is generated, so use it for debug only - - If NULL creates a new list, otherwise clears and fills this one (and thus saves allocations) - - - - Returns a list of all active tweens with the given id. - Returns NULL if there are no active tweens with the given id. - Beware: each time you call this method a new list is generated - - If TRUE returns only the tweens with the given ID that are currently playing - If NULL creates a new list, otherwise clears and fills this one (and thus saves allocations) - - - - Returns a list of all active tweens with the given target. - Returns NULL if there are no active tweens with the given target. - Beware: each time you call this method a new list is generated - If TRUE returns only the tweens with the given target that are currently playing - If NULL creates a new list, otherwise clears and fills this one (and thus saves allocations) - - - - - Creates virtual tweens that can be used to change other elements via their OnUpdate calls - - - - - Tweens a virtual float. - You can add regular settings to the generated tween, - but do not use SetUpdate or you will overwrite the onVirtualUpdate parameter - - The value to start from - The value to tween to - The duration of the tween - A callback which must accept a parameter of type float, called at each update - - - - Tweens a virtual int. - You can add regular settings to the generated tween, - but do not use SetUpdate or you will overwrite the onVirtualUpdate parameter - - The value to start from - The value to tween to - The duration of the tween - A callback which must accept a parameter of type int, called at each update - - - - Tweens a virtual Vector3. - You can add regular settings to the generated tween, - but do not use SetUpdate or you will overwrite the onVirtualUpdate parameter - - The value to start from - The value to tween to - The duration of the tween - A callback which must accept a parameter of type Vector3, called at each update - - - - Tweens a virtual Color. - You can add regular settings to the generated tween, - but do not use SetUpdate or you will overwrite the onVirtualUpdate parameter - - The value to start from - The value to tween to - The duration of the tween - A callback which must accept a parameter of type Color, called at each update - - - Returns a value based on the given ease and lifetime percentage (0 to 1) - The value to start from when lifetimePercentage is 0 - The value to reach when lifetimePercentage is 1 - The time percentage (0 to 1) at which the value should be taken - The type of ease - - - Returns a value based on the given ease and lifetime percentage (0 to 1) - The value to start from when lifetimePercentage is 0 - The value to reach when lifetimePercentage is 1 - The time percentage (0 to 1) at which the value should be taken - The type of ease - Eventual overshoot to use with Back ease - - - Returns a value based on the given ease and lifetime percentage (0 to 1) - The value to start from when lifetimePercentage is 0 - The value to reach when lifetimePercentage is 1 - The time percentage (0 to 1) at which the value should be taken - The type of ease - Eventual amplitude to use with Elastic easeType - Eventual period to use with Elastic easeType - - - Returns a value based on the given ease and lifetime percentage (0 to 1) - The value to start from when lifetimePercentage is 0 - The value to reach when lifetimePercentage is 1 - The time percentage (0 to 1) at which the value should be taken - The AnimationCurve to use for ease - - - Fires the given callback after the given time. - Callback delay - Callback to fire when the delay has expired - If TRUE (default) ignores Unity's timeScale - - - - Don't assign this! It's assigned automatically when creating 0 duration tweens - - - - - Don't assign this! It's assigned automatically when setting the ease to an AnimationCurve or to a custom ease function - - - - - Allows to wrap ease method in special ways, adding extra features - - - - - Converts the given ease so that it also creates a stop-motion effect, by playing the tween at the given FPS - - FPS at which the tween should be played - Ease type - - - - Converts the given ease so that it also creates a stop-motion effect, by playing the tween at the given FPS - - FPS at which the tween should be played - AnimationCurve to use for the ease - - - - Converts the given ease so that it also creates a stop-motion effect, by playing the tween at the given FPS - - FPS at which the tween should be played - Custom ease function to use - - - - Used to allow method chaining with DOTween.Init - - - - - Directly sets the current max capacity of Tweeners and Sequences - (meaning how many Tweeners and Sequences can be running at the same time), - so that DOTween doesn't need to automatically increase them in case the max is reached - (which might lead to hiccups when that happens). - Sequences capacity must be less or equal to Tweeners capacity - (if you pass a low Tweener capacity it will be automatically increased to match the Sequence's). - Beware: use this method only when there are no tweens running. - - Max Tweeners capacity. - Default: 200 - Max Sequences capacity. - Default: 50 - - - - Behaviour that can be assigned when chaining a SetLink to a tween - - - - Pauses the tween when the link target is disabled - - - Pauses the tween when the link target is disabled, plays it when it's enabled - - - Pauses the tween when the link target is disabled, restarts it when it's enabled - - - Plays the tween when the link target is enabled - - - Restarts the tween when the link target is enabled - - - Kills the tween when the link target is disabled - - - Kills the tween when the link target is destroyed (becomes NULL). This is always active even if another behaviour is chosen - - - Completes the tween when the link target is disabled - - - Completes and kills the tween when the link target is disabled - - - Rewinds the tween (delay excluded) when the link target is disabled - - - Rewinds and kills the tween when the link target is disabled - - - - Path mode (used to determine correct LookAt orientation) - - - - Ignores the path mode (and thus LookAt behaviour) - - - Regular 3D path - - - 2D top-down path - - - 2D side-scroller path - - - - Type of path to use with DOPath tweens - - - - Linear, composed of straight segments between each waypoint - - - Curved path (which uses Catmull-Rom curves) - - - EXPERIMENTAL: Curved path (which uses Cubic Bezier curves, where each point requires two extra control points) - - - - Tweens a Vector2 along a circle. - EndValue represents the center of the circle, start and end value degrees are inside options - ChangeValue x is changeValue°, y is unused - - - - - Path control point - - - - - Path waypoints (modified by PathPlugin when setting relative end/change value or by CubicBezierDecoder) and by DOTweenPathInspector - - - - - Minimum input points necessary to create the path (doesn't correspond to actual waypoints required) - - - - - Gets the point on the path at the given percentage (0 to 1) - - The percentage (0 to 1) at which to get the point - If TRUE constant speed is taken into account, otherwise not - - - - Base interface for all tween plugins options - - - - Resets the plugin - - - - This plugin generates some GC allocations at startup - - - - - Path plugin works exclusively with Transforms - - - - - Rotation mode used with DORotate methods - - - - - Fastest way that never rotates beyond 360° - - - - - Fastest way that rotates beyond 360° - - - - - Adds the given rotation to the transform using world axis and an advanced precision mode - (like when using transform.Rotate(Space.World)). - In this mode the end value is is always considered relative - - - - - Adds the given rotation to the transform's local axis - (like when rotating an object with the "local" switch enabled in Unity's editor or using transform.Rotate(Space.Self)). - In this mode the end value is is always considered relative - - - - - Type of scramble to apply to string tweens - - - - - No scrambling of characters - - - - - A-Z + a-z + 0-9 characters - - - - - A-Z characters - - - - - a-z characters - - - - - 0-9 characters - - - - - Custom characters - - - - - Methods that extend Tween objects and allow to control or get data from them - - - - Completes the tween - - - Completes the tween - For Sequences only: if TRUE also internal Sequence callbacks will be fired, - otherwise they will be ignored - - - Flips the direction of this tween (backwards if it was going forward or viceversa) - - - Forces the tween to initialize its settings immediately - - - Send the tween to the given position in time - Time position to reach - (if higher than the whole tween duration the tween will simply reach its end) - If TRUE will play the tween after reaching the given position, otherwise it will pause it - - - Send the tween to the given position in time while also executing any callback between the previous time position and the new one - Time position to reach - (if higher than the whole tween duration the tween will simply reach its end) - If TRUE will play the tween after reaching the given position, otherwise it will pause it - - - Kills the tween - If TRUE completes the tween before killing it - - - - Forces this tween to update manually, regardless of the set via SetUpdate. - Note that the tween will still be subject to normal tween rules, so if for example it's paused this method will do nothing. - Also note that if you only want to update this tween instance manually you'll have to set it to anyway, - so that it's not updated automatically. - - Manual deltaTime - Unscaled delta time (used with tweens set as timeScaleIndependent) - - - Pauses the tween - - - Plays the tween - - - Sets the tween in a backwards direction and plays it - - - Sets the tween in a forward direction and plays it - - - Restarts the tween from the beginning - Ignored in case of Sequences. If TRUE includes the eventual tween delay, otherwise skips it - Ignored in case of Sequences. If >= 0 changes the startup delay to this value, otherwise doesn't touch it - - - Rewinds and pauses the tween - Ignored in case of Sequences. If TRUE includes the eventual tween delay, otherwise skips it - - - Smoothly rewinds the tween (delays excluded). - A "smooth rewind" animates the tween to its start position, - skipping all elapsed loops (except in case of LoopType.Incremental) while keeping the animation fluent. - If called on a tween who is still waiting for its delay to happen, it will simply set the delay to 0 and pause the tween. - Note that a tween that was smoothly rewinded will have its play direction flipped - - - Plays the tween if it was paused, pauses it if it was playing - - - Send a path tween to the given waypoint. - Has no effect if this is not a path tween. - BEWARE, this is a special utility method: - it works only with Linear eases. Also, the lookAt direction might be wrong after calling this and might need to be set manually - (because it relies on a smooth path movement and doesn't work well with jumps that encompass dramatic direction changes) - Waypoint index to reach - (if higher than the max waypoint index the tween will simply go to the last one) - If TRUE will play the tween after reaching the given waypoint, otherwise it will pause it - - - - Creates a yield instruction that waits until the tween is killed or complete. - It can be used inside a coroutine as a yield. - Example usage:yield return myTween.WaitForCompletion(); - - - - - Creates a yield instruction that waits until the tween is killed or rewinded. - It can be used inside a coroutine as a yield. - Example usage:yield return myTween.WaitForRewind(); - - - - - Creates a yield instruction that waits until the tween is killed. - It can be used inside a coroutine as a yield. - Example usage:yield return myTween.WaitForKill(); - - - - - Creates a yield instruction that waits until the tween is killed or has gone through the given amount of loops. - It can be used inside a coroutine as a yield. - Example usage:yield return myTween.WaitForElapsedLoops(2); - - Elapsed loops to wait for - - - - Creates a yield instruction that waits until the tween is killed or has reached the given position (loops included, delays excluded). - It can be used inside a coroutine as a yield. - Example usage:yield return myTween.WaitForPosition(2.5f); - - Position (loops included, delays excluded) to wait for - - - - Creates a yield instruction that waits until the tween is killed or started - (meaning when the tween is set in a playing state the first time, after any eventual delay). - It can be used inside a coroutine as a yield. - Example usage:yield return myTween.WaitForStart(); - - - - Returns the total number of loops completed by this tween - - - Returns the eventual delay set for this tween - - - Returns the eventual elapsed delay set for this tween - - - Returns the duration of this tween (delays excluded). - NOTE: when using settings like SpeedBased, the duration will be recalculated when the tween starts - If TRUE returns the full duration loops included, - otherwise the duration of a single loop cycle - - - Returns the elapsed time for this tween (delays exluded) - If TRUE returns the elapsed time since startup loops included, - otherwise the elapsed time within the current loop cycle - - - Returns the elapsed percentage (0 to 1) of this tween (delays exluded) - If TRUE returns the elapsed percentage since startup loops included, - otherwise the elapsed percentage within the current loop cycle - - - Returns the elapsed percentage (0 to 1) of this tween (delays exluded), - based on a single loop, and calculating eventual backwards Yoyo loops as 1 to 0 instead of 0 to 1 - - - Returns FALSE if this tween has been killed or is NULL, TRUE otherwise. - BEWARE: if this tween is recyclable it might have been spawned again for another use and thus return TRUE anyway. - When working with recyclable tweens you should take care to know when a tween has been killed and manually set your references to NULL. - If you want to be sure your references are set to NULL when a tween is killed you can use the OnKill callback like this: - .OnKill(()=> myTweenReference = null) - - - Returns TRUE if this tween was reversed and is set to go backwards - - - Returns TRUE if the tween is complete - (silently fails and returns FALSE if the tween has been killed) - - - Returns TRUE if this tween has been initialized - - - Returns TRUE if this tween is playing - - - Returns the total number of loops set for this tween - (returns -1 if the loops are infinite) - - - - Returns a point on a path based on the given path percentage. - Returns Vector3.zero if this is not a path tween, if the tween is invalid, or if the path is not yet initialized. - A path is initialized after its tween starts, or immediately if the tween was created with the Path Editor (DOTween Pro feature). - You can force a path to be initialized by calling myTween.ForceInit(). - - Percentage of the path (0 to 1) on which to get the point - - - - Returns an array of points that can be used to draw the path. - Note that this method generates allocations, because it creates a new array. - Returns NULL if this is not a path tween, if the tween is invalid, or if the path is not yet initialized. - A path is initialized after its tween starts, or immediately if the tween was created with the Path Editor (DOTween Pro feature). - You can force a path to be initialized by calling myTween.ForceInit(). - - How many points to create for each path segment (waypoint to waypoint). - Only used in case of non-Linear paths - - - - Returns the length of a path. - Returns -1 if this is not a path tween, if the tween is invalid, or if the path is not yet initialized. - A path is initialized after its tween starts, or immediately if the tween was created with the Path Editor (DOTween Pro feature). - You can force a path to be initialized by calling myTween.ForceInit(). - - - - - Types of loop - - - - Each loop cycle restarts from the beginning - - - The tween moves forward and backwards at alternate cycles - - - Continuously increments the tween at the end of each loop cycle (A to B, B to B+(A-B), and so on), thus always moving "onward". - In case of String tweens works only if the tween is set as relative - - - - Controls other tweens as a group - - - - - Methods that extend known Unity objects and allow to directly create and control tweens from their instances - - - - Tweens a Camera's aspect to the given value. - Also stores the camera as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Camera's backgroundColor to the given value. - Also stores the camera as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Camera's farClipPlane to the given value. - Also stores the camera as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Camera's fieldOfView to the given value. - Also stores the camera as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Camera's nearClipPlane to the given value. - Also stores the camera as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Camera's orthographicSize to the given value. - Also stores the camera as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Camera's pixelRect to the given value. - Also stores the camera as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Camera's rect to the given value. - Also stores the camera as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Shakes a Camera's localPosition along its relative X Y axes with the given values. - Also stores the camera as the tween's target so it can be used for filtered operations - The duration of the tween - The shake strength - Indicates how much will the shake vibrate - Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). - Setting it to 0 will shake along a single direction. - If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not - - - Shakes a Camera's localPosition along its relative X Y axes with the given values. - Also stores the camera as the tween's target so it can be used for filtered operations - The duration of the tween - The shake strength on each axis - Indicates how much will the shake vibrate - Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). - Setting it to 0 will shake along a single direction. - If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not - - - Shakes a Camera's localRotation. - Also stores the camera as the tween's target so it can be used for filtered operations - The duration of the tween - The shake strength - Indicates how much will the shake vibrate - Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). - Setting it to 0 will shake along a single direction. - If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not - - - Shakes a Camera's localRotation. - Also stores the camera as the tween's target so it can be used for filtered operations - The duration of the tween - The shake strength on each axis - Indicates how much will the shake vibrate - Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). - Setting it to 0 will shake along a single direction. - If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not - - - Tweens a Light's color to the given value. - Also stores the light as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Light's intensity to the given value. - Also stores the light as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Light's shadowStrength to the given value. - Also stores the light as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a LineRenderer's color to the given value. - Also stores the LineRenderer as the tween's target so it can be used for filtered operations. - Note that this method requires to also insert the start colors for the tween, - since LineRenderers have no way to get them. - The start value to tween from - The end value to reachThe duration of the tween - - - Tweens a Material's color to the given value. - Also stores the material as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Material's named color property to the given value. - Also stores the material as the tween's target so it can be used for filtered operations - The end value to reach - The name of the material property to tween (like _Tint or _SpecColor) - The duration of the tween - - - Tweens a Material's named color property with the given ID to the given value. - Also stores the material as the tween's target so it can be used for filtered operations - The end value to reach - The ID of the material property to tween (also called nameID in Unity's manual) - The duration of the tween - - - Tweens a Material's alpha color to the given value - (will have no effect unless your material supports transparency). - Also stores the material as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Material's alpha color to the given value - (will have no effect unless your material supports transparency). - Also stores the material as the tween's target so it can be used for filtered operations - The end value to reach - The name of the material property to tween (like _Tint or _SpecColor) - The duration of the tween - - - Tweens a Material's alpha color with the given ID to the given value - (will have no effect unless your material supports transparency). - Also stores the material as the tween's target so it can be used for filtered operations - The end value to reach - The ID of the material property to tween (also called nameID in Unity's manual) - The duration of the tween - - - Tweens a Material's named float property to the given value. - Also stores the material as the tween's target so it can be used for filtered operations - The end value to reach - The name of the material property to tween - The duration of the tween - - - Tweens a Material's named float property with the given ID to the given value. - Also stores the material as the tween's target so it can be used for filtered operations - The end value to reach - The ID of the material property to tween (also called nameID in Unity's manual) - The duration of the tween - - - Tweens a Material's texture offset to the given value. - Also stores the material as the tween's target so it can be used for filtered operations - The end value to reach - The duration of the tween - - - Tweens a Material's named texture offset property to the given value. - Also stores the material as the tween's target so it can be used for filtered operations - The end value to reach - The name of the material property to tween - The duration of the tween - - - Tweens a Material's texture scale to the given value. - Also stores the material as the tween's target so it can be used for filtered operations - The end value to reach - The duration of the tween - - - Tweens a Material's named texture scale property to the given value. - Also stores the material as the tween's target so it can be used for filtered operations - The end value to reach - The name of the material property to tween - The duration of the tween - - - Tweens a Material's named Vector property to the given value. - Also stores the material as the tween's target so it can be used for filtered operations - The end value to reach - The name of the material property to tween - The duration of the tween - - - Tweens a Material's named Vector property with the given ID to the given value. - Also stores the material as the tween's target so it can be used for filtered operations - The end value to reach - The ID of the material property to tween (also called nameID in Unity's manual) - The duration of the tween - - - Tweens a TrailRenderer's startWidth/endWidth to the given value. - Also stores the TrailRenderer as the tween's target so it can be used for filtered operations - The end startWidth to reachThe end endWidth to reach - The duration of the tween - - - Tweens a TrailRenderer's time to the given value. - Also stores the TrailRenderer as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Transform's position to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - If TRUE the tween will smoothly snap all values to integers - - - Tweens a Transform's X position to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - If TRUE the tween will smoothly snap all values to integers - - - Tweens a Transform's Y position to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - If TRUE the tween will smoothly snap all values to integers - - - Tweens a Transform's Z position to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - If TRUE the tween will smoothly snap all values to integers - - - Tweens a Transform's localPosition to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - If TRUE the tween will smoothly snap all values to integers - - - Tweens a Transform's X localPosition to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - If TRUE the tween will smoothly snap all values to integers - - - Tweens a Transform's Y localPosition to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - If TRUE the tween will smoothly snap all values to integers - - - Tweens a Transform's Z localPosition to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - If TRUE the tween will smoothly snap all values to integers - - - Tweens a Transform's rotation to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - Rotation mode - - - Tweens a Transform's rotation to the given value using pure quaternion values. - Also stores the transform as the tween's target so it can be used for filtered operations. - PLEASE NOTE: DORotate, which takes Vector3 values, is the preferred rotation method. - This method was implemented for very special cases, and doesn't support LoopType.Incremental loops - (neither for itself nor if placed inside a LoopType.Incremental Sequence) - - The end value to reachThe duration of the tween - - - Tweens a Transform's localRotation to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - Rotation mode - - - Tweens a Transform's rotation to the given value using pure quaternion values. - Also stores the transform as the tween's target so it can be used for filtered operations. - PLEASE NOTE: DOLocalRotate, which takes Vector3 values, is the preferred rotation method. - This method was implemented for very special cases, and doesn't support LoopType.Incremental loops - (neither for itself nor if placed inside a LoopType.Incremental Sequence) - - The end value to reachThe duration of the tween - - - Tweens a Transform's localScale to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Transform's localScale uniformly to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Transform's X localScale to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Transform's Y localScale to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Transform's Z localScale to the given value. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Transform's rotation so that it will look towards the given world position. - Also stores the transform as the tween's target so it can be used for filtered operations - The position to look atThe duration of the tween - Eventual axis constraint for the rotation - The vector that defines in which direction up is (default: Vector3.up) - - - EXPERIMENTAL Tweens a Transform's rotation so that it will look towards the given world position, - while also updating the lookAt position every frame - (contrary to which calculates the lookAt rotation only once, when the tween starts). - Also stores the transform as the tween's target so it can be used for filtered operations - The position to look atThe duration of the tween - Eventual axis constraint for the rotation - The vector that defines in which direction up is (default: Vector3.up) - - - Punches a Transform's localPosition towards the given direction and then back to the starting one - as if it was connected to the starting position via an elastic. - The direction and strength of the punch (added to the Transform's current position) - The duration of the tween - Indicates how much will the punch vibrate - Represents how much (0 to 1) the vector will go beyond the starting position when bouncing backwards. - 1 creates a full oscillation between the punch direction and the opposite direction, - while 0 oscillates only between the punch and the start position - If TRUE the tween will smoothly snap all values to integers - - - Punches a Transform's localScale towards the given size and then back to the starting one - as if it was connected to the starting scale via an elastic. - The punch strength (added to the Transform's current scale) - The duration of the tween - Indicates how much will the punch vibrate - Represents how much (0 to 1) the vector will go beyond the starting size when bouncing backwards. - 1 creates a full oscillation between the punch scale and the opposite scale, - while 0 oscillates only between the punch scale and the start scale - - - Punches a Transform's localRotation towards the given size and then back to the starting one - as if it was connected to the starting rotation via an elastic. - The punch strength (added to the Transform's current rotation) - The duration of the tween - Indicates how much will the punch vibrate - Represents how much (0 to 1) the vector will go beyond the starting rotation when bouncing backwards. - 1 creates a full oscillation between the punch rotation and the opposite rotation, - while 0 oscillates only between the punch and the start rotation - - - Shakes a Transform's localPosition with the given values. - The duration of the tween - The shake strength - Indicates how much will the shake vibrate - Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). - Setting it to 0 will shake along a single direction. - If TRUE the tween will smoothly snap all values to integers - If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not - - - Shakes a Transform's localPosition with the given values. - The duration of the tween - The shake strength on each axis - Indicates how much will the shake vibrate - Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). - Setting it to 0 will shake along a single direction. - If TRUE the tween will smoothly snap all values to integers - If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not - - - Shakes a Transform's localRotation. - The duration of the tween - The shake strength - Indicates how much will the shake vibrate - Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). - Setting it to 0 will shake along a single direction. - If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not - - - Shakes a Transform's localRotation. - The duration of the tween - The shake strength on each axis - Indicates how much will the shake vibrate - Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). - Setting it to 0 will shake along a single direction. - If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not - - - Shakes a Transform's localScale. - The duration of the tween - The shake strength - Indicates how much will the shake vibrate - Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). - Setting it to 0 will shake along a single direction. - If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not - - - Shakes a Transform's localScale. - The duration of the tween - The shake strength on each axis - Indicates how much will the shake vibrate - Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). - Setting it to 0 will shake along a single direction. - If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not - - - Tweens a Transform's position to the given value, while also applying a jump effect along the Y axis. - Returns a Sequence instead of a Tweener. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reach - Power of the jump (the max height of the jump is represented by this plus the final Y offset) - Total number of jumps - The duration of the tween - If TRUE the tween will smoothly snap all values to integers - - - Tweens a Transform's localPosition to the given value, while also applying a jump effect along the Y axis. - Returns a Sequence instead of a Tweener. - Also stores the transform as the tween's target so it can be used for filtered operations - The end value to reach - Power of the jump (the max height of the jump is represented by this plus the final Y offset) - Total number of jumps - The duration of the tween - If TRUE the tween will smoothly snap all values to integers - - - Tweens a Transform's position through the given path waypoints, using the chosen path algorithm. - Also stores the transform as the tween's target so it can be used for filtered operations - The waypoints to go through - The duration of the tween - The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points) - The path mode: 3D, side-scroller 2D, top-down 2D - The resolution of the path (useless in case of Linear paths): higher resolutions make for more detailed curved paths but are more expensive. - Defaults to 10, but a value of 5 is usually enough if you don't have dramatic long curves between waypoints - The color of the path (shown when gizmos are active in the Play panel and the tween is running) - - - Tweens a Transform's localPosition through the given path waypoints, using the chosen path algorithm. - Also stores the transform as the tween's target so it can be used for filtered operations - The waypoint to go through - The duration of the tween - The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points) - The path mode: 3D, side-scroller 2D, top-down 2D - The resolution of the path: higher resolutions make for more detailed curved paths but are more expensive. - Defaults to 10, but a value of 5 is usually enough if you don't have dramatic long curves between waypoints - The color of the path (shown when gizmos are active in the Play panel and the tween is running) - - - IMPORTANT: Unless you really know what you're doing, you should use the overload that accepts a Vector3 array instead. - Tweens a Transform's position via the given path. - Also stores the transform as the tween's target so it can be used for filtered operations - The path to use - The duration of the tween - The path mode: 3D, side-scroller 2D, top-down 2D - - - IMPORTANT: Unless you really know what you're doing, you should use the overload that accepts a Vector3 array instead. - Tweens a Transform's localPosition via the given path. - Also stores the transform as the tween's target so it can be used for filtered operations - The path to use - The duration of the tween - The path mode: 3D, side-scroller 2D, top-down 2D - - - Tweens a Tween's timeScale to the given value. - Also stores the Tween as the tween's target so it can be used for filtered operations - The end value to reachThe duration of the tween - - - Tweens a Light's color to the given value, - in a way that allows other DOBlendableColor tweens to work together on the same target, - instead than fight each other as multiple DOColor would do. - Also stores the Light as the tween's target so it can be used for filtered operations - The value to tween toThe duration of the tween - - - Tweens a Material's color to the given value, - in a way that allows other DOBlendableColor tweens to work together on the same target, - instead than fight each other as multiple DOColor would do. - Also stores the Material as the tween's target so it can be used for filtered operations - The value to tween toThe duration of the tween - - - Tweens a Material's named color property to the given value, - in a way that allows other DOBlendableColor tweens to work together on the same target, - instead than fight each other as multiple DOColor would do. - Also stores the Material as the tween's target so it can be used for filtered operations - The value to tween to - The name of the material property to tween (like _Tint or _SpecColor) - The duration of the tween - - - Tweens a Material's named color property with the given ID to the given value, - in a way that allows other DOBlendableColor tweens to work together on the same target, - instead than fight each other as multiple DOColor would do. - Also stores the Material as the tween's target so it can be used for filtered operations - The value to tween to - The ID of the material property to tween (also called nameID in Unity's manual) - The duration of the tween - - - Tweens a Transform's position BY the given value (as if you chained a SetRelative), - in a way that allows other DOBlendableMove tweens to work together on the same target, - instead than fight each other as multiple DOMove would do. - Also stores the transform as the tween's target so it can be used for filtered operations - The value to tween byThe duration of the tween - If TRUE the tween will smoothly snap all values to integers - - - Tweens a Transform's localPosition BY the given value (as if you chained a SetRelative), - in a way that allows other DOBlendableMove tweens to work together on the same target, - instead than fight each other as multiple DOMove would do. - Also stores the transform as the tween's target so it can be used for filtered operations - The value to tween byThe duration of the tween - If TRUE the tween will smoothly snap all values to integers - - - EXPERIMENTAL METHOD - Tweens a Transform's rotation BY the given value (as if you chained a SetRelative), - in a way that allows other DOBlendableRotate tweens to work together on the same target, - instead than fight each other as multiple DORotate would do. - Also stores the transform as the tween's target so it can be used for filtered operations - The value to tween byThe duration of the tween - Rotation mode - - - EXPERIMENTAL METHOD - Tweens a Transform's lcoalRotation BY the given value (as if you chained a SetRelative), - in a way that allows other DOBlendableRotate tweens to work together on the same target, - instead than fight each other as multiple DORotate would do. - Also stores the transform as the tween's target so it can be used for filtered operations - The value to tween byThe duration of the tween - Rotation mode - - - Punches a Transform's localRotation BY the given value and then back to the starting one - as if it was connected to the starting rotation via an elastic. Does it in a way that allows other - DOBlendableRotate tweens to work together on the same target - The punch strength (added to the Transform's current rotation) - The duration of the tween - Indicates how much will the punch vibrate - Represents how much (0 to 1) the vector will go beyond the starting rotation when bouncing backwards. - 1 creates a full oscillation between the punch rotation and the opposite rotation, - while 0 oscillates only between the punch and the start rotation - - - Tweens a Transform's localScale BY the given value (as if you chained a SetRelative), - in a way that allows other DOBlendableScale tweens to work together on the same target, - instead than fight each other as multiple DOScale would do. - Also stores the transform as the tween's target so it can be used for filtered operations - The value to tween byThe duration of the tween - - - - Completes all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens completed - (meaning the tweens that don't have infinite loops and were not already complete) - - For Sequences only: if TRUE also internal Sequence callbacks will be fired, - otherwise they will be ignored - - - - Completes all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens completed - (meaning the tweens that don't have infinite loops and were not already complete) - - For Sequences only: if TRUE also internal Sequence callbacks will be fired, - otherwise they will be ignored - - - - Kills all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens killed. - - If TRUE completes the tween before killing it - - - - Kills all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens killed. - - If TRUE completes the tween before killing it - - - - Flips the direction (backwards if it was going forward or viceversa) of all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens flipped. - - - - - Flips the direction (backwards if it was going forward or viceversa) of all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens flipped. - - - - - Sends to the given position all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens involved. - - Time position to reach - (if higher than the whole tween duration the tween will simply reach its end) - If TRUE will play the tween after reaching the given position, otherwise it will pause it - - - - Sends to the given position all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens involved. - - Time position to reach - (if higher than the whole tween duration the tween will simply reach its end) - If TRUE will play the tween after reaching the given position, otherwise it will pause it - - - - Pauses all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens paused. - - - - - Pauses all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens paused. - - - - - Plays all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens played. - - - - - Plays all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens played. - - - - - Plays backwards all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens played. - - - - - Plays backwards all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens played. - - - - - Plays forward all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens played. - - - - - Plays forward all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens played. - - - - - Restarts all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens restarted. - - - - - Restarts all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens restarted. - - - - - Rewinds all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens rewinded. - - - - - Rewinds all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens rewinded. - - - - - Smoothly rewinds all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens rewinded. - - - - - Smoothly rewinds all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens rewinded. - - - - - Toggles the paused state (plays if it was paused, pauses if it was playing) of all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens involved. - - - - - Toggles the paused state (plays if it was paused, pauses if it was playing) of all tweens that have this target as a reference - (meaning tweens that were started from this target, or that had this target added as an Id) - and returns the total number of tweens involved. - - - - - This class serves only as a utility class to store tween settings to apply on multiple tweens. - It is in no way needed otherwise, since you can directly apply tween settings to a tween via chaining - - - - A variable you can eventually Clear and reuse when needed, - to avoid instantiating TweenParams objects - - - Creates a new TweenParams object, which you can use to store tween settings - to pass to multiple tweens via myTween.SetAs(myTweenParms) - - - Clears and resets this TweenParams instance using default values, - so it can be reused without instantiating another one - - - Sets the autoKill behaviour of the tween. - Has no effect if the tween has already started - If TRUE the tween will be automatically killed when complete - - - Sets an ID for the tween, which can then be used as a filter with DOTween's static methods. - The ID to assign to this tween. Can be an int, a string, an object or anything else. - - - Sets the target for the tween, which can then be used as a filter with DOTween's static methods. - IMPORTANT: use it with caution. If you just want to set an ID for the tween use SetId instead. - When using shorcuts the shortcut target is already assigned as the tween's target, - so using this method will overwrite it and prevent shortcut-operations like myTarget.DOPause from working correctly. - The target to assign to this tween. Can be an int, a string, an object or anything else. - - - Sets the looping options for the tween. - Has no effect if the tween has already started - Number of cycles to play (-1 for infinite - will be converted to 1 in case the tween is nested in a Sequence) - Loop behaviour type (default: LoopType.Restart) - - - Sets the ease of the tween. - If applied to Sequences eases the whole sequence animation - Eventual overshoot or amplitude to use with Back or Elastic easeType (default is 1.70158) - Eventual period to use with Elastic easeType (default is 0) - - - Sets the ease of the tween using an AnimationCurve. - If applied to Sequences eases the whole sequence animation - - - Sets the ease of the tween using a custom ease function. - If applied to Sequences eases the whole sequence animation - - - Sets the recycling behaviour for the tween. - If TRUE the tween will be recycled after being killed, otherwise it will be destroyed. - - - Sets the update type to the one defined in DOTween.defaultUpdateType (UpdateType.Normal unless changed) - and lets you choose if it should be independent from Unity's Time.timeScale - If TRUE the tween will ignore Unity's Time.timeScale - - - Sets the type of update (default or independent) for the tween - The type of update (default: UpdateType.Normal) - If TRUE the tween will ignore Unity's Time.timeScale - - - Sets the onStart callback for the tween. - Called the first time the tween is set in a playing state, after any eventual delay - - - Sets the onPlay callback for the tween. - Called when the tween is set in a playing state, after any eventual delay. - Also called each time the tween resumes playing from a paused state - - - Sets the onRewind callback for the tween. - Called when the tween is rewinded, - either by calling Rewind or by reaching the start position while playing backwards. - Rewinding a tween that is already rewinded will not fire this callback - - - Sets the onUpdate callback for the tween. - Called each time the tween updates - - - Sets the onStepComplete callback for the tween. - Called the moment the tween completes one loop cycle, even when going backwards - - - Sets the onComplete callback for the tween. - Called the moment the tween reaches its final forward position, loops included - - - Sets the onKill callback for the tween. - Called the moment the tween is killed - - - Sets the onWaypointChange callback for the tween. - Called when a path tween reaches a new waypoint - - - Sets a delayed startup for the tween. - Has no effect on Sequences or if the tween has already started - - - If isRelative is TRUE sets the tween as relative - (the endValue will be calculated as startValue + endValue instead than being used directly). - Has no effect on Sequences or if the tween has already started - - - If isSpeedBased is TRUE sets the tween as speed based - (the duration will represent the number of units the tween moves x second). - Has no effect on Sequences, nested tweens, or if the tween has already started - - - - Methods that extend Tween objects and allow to set their parameters - - - - Sets the autoKill behaviour of the tween to TRUE. - Has no effect if the tween has already started or if it's added to a Sequence - - - Sets the autoKill behaviour of the tween. - Has no effect if the tween has already started or if it's added to a Sequence - If TRUE the tween will be automatically killed when complete - - - Sets an ID for the tween (), which can then be used as a filter with DOTween's static methods. - The ID to assign to this tween. Can be an int, a string, an object or anything else. - - - Sets a string ID for the tween (), which can then be used as a filter with DOTween's static methods. - Filtering via string is 2X faster than using an object as an ID (using the alternate obejct overload) - The string ID to assign to this tween. - - - Sets an int ID for the tween (), which can then be used as a filter with DOTween's static methods. - Filtering via int is 4X faster than via object, 2X faster than via string (using the alternate object/string overloads) - The int ID to assign to this tween. - - - Allows to link this tween to a GameObject - so that it will be automatically killed when the GameObject is destroyed. - Has no effect if the tween is added to a Sequence - The link target (unrelated to the target set via SetTarget) - - - Allows to link this tween to a GameObject and assign a behaviour depending on it. - This will also automatically kill the tween when the GameObject is destroyed. - Has no effect if the tween is added to a Sequence - The link target (unrelated to the target set via SetTarget) - The behaviour to use ( is always evaluated even if you choose another one) - - - Sets the target for the tween, which can then be used as a filter with DOTween's static methods. - IMPORTANT: use it with caution. If you just want to set an ID for the tween use SetId instead. - When using shorcuts the shortcut target is already assigned as the tween's target, - so using this method will overwrite it and prevent shortcut-operations like myTarget.DOPause from working correctly. - The target to assign to this tween. Can be an int, a string, an object or anything else. - - - Sets the looping options for the tween. - Has no effect if the tween has already started - Number of cycles to play (-1 for infinite - will be converted to 1 in case the tween is nested in a Sequence) - - - Sets the looping options for the tween. - Has no effect if the tween has already started - Number of cycles to play (-1 for infinite - will be converted to 1 in case the tween is nested in a Sequence) - Loop behaviour type (default: LoopType.Restart) - - - Sets the ease of the tween. - If applied to Sequences eases the whole sequence animation - - - Sets the ease of the tween. - If applied to Sequences eases the whole sequence animation - - Eventual overshoot to use with Back or Flash ease (default is 1.70158 - 1 for Flash). - In case of Flash ease it must be an intenger and sets the total number of flashes that will happen. - Using an even number will complete the tween on the starting value, while an odd one will complete it on the end value. - - - - Sets the ease of the tween. - If applied to Sequences eases the whole sequence animation - Eventual amplitude to use with Elastic easeType or overshoot to use with Flash easeType (default is 1.70158 - 1 for Flash). - In case of Flash ease it must be an integer and sets the total number of flashes that will happen. - Using an even number will complete the tween on the starting value, while an odd one will complete it on the end value. - - Eventual period to use with Elastic or Flash easeType (default is 0). - In case of Flash ease it indicates the power in time of the ease, and must be between -1 and 1. - 0 is balanced, 1 weakens the ease with time, -1 starts the ease weakened and gives it power towards the end. - - - - Sets the ease of the tween using an AnimationCurve. - If applied to Sequences eases the whole sequence animation - - - Sets the ease of the tween using a custom ease function (which must return a value between 0 and 1). - If applied to Sequences eases the whole sequence animation - - - Allows the tween to be recycled after being killed. - - - Sets the recycling behaviour for the tween. - If TRUE the tween will be recycled after being killed, otherwise it will be destroyed. - - - Sets the update type to UpdateType.Normal and lets you choose if it should be independent from Unity's Time.timeScale - If TRUE the tween will ignore Unity's Time.timeScale - - - Sets the type of update for the tween - The type of update (defalt: UpdateType.Normal) - - - Sets the type of update for the tween and lets you choose if it should be independent from Unity's Time.timeScale - The type of update - If TRUE the tween will ignore Unity's Time.timeScale - - - EXPERIMENTAL: inverts this tween, so that it will play from the end to the beginning - (playing it backwards will actually play it from the beginning to the end). - Has no effect if the tween has already started or if it's added to a Sequence - - - EXPERIMENTAL: inverts this tween, so that it will play from the end to the beginning - (playing it backwards will actually play it from the beginning to the end). - Has no effect if the tween has already started or if it's added to a Sequence - If TRUE the tween will be inverted, otherwise it won't - - - Sets the onStart callback for the tween, clearing any previous onStart callback that was set. - Called the first time the tween is set in a playing state, after any eventual delay - - - Sets the onPlay callback for the tween, clearing any previous onPlay callback that was set. - Called when the tween is set in a playing state, after any eventual delay. - Also called each time the tween resumes playing from a paused state - - - Sets the onPause callback for the tween, clearing any previous onPause callback that was set. - Called when the tween state changes from playing to paused. - If the tween has autoKill set to FALSE, this is called also when the tween reaches completion. - - - Sets the onRewind callback for the tween, clearing any previous onRewind callback that was set. - Called when the tween is rewinded, - either by calling Rewind or by reaching the start position while playing backwards. - Rewinding a tween that is already rewinded will not fire this callback - - - Sets the onUpdate callback for the tween, clearing any previous onUpdate callback that was set. - Called each time the tween updates - - - Sets the onStepComplete callback for the tween, clearing any previous onStepComplete callback that was set. - Called the moment the tween completes one loop cycle, even when going backwards - - - Sets the onComplete callback for the tween, clearing any previous onComplete callback that was set. - Called the moment the tween reaches its final forward position, loops included - - - Sets the onKill callback for the tween, clearing any previous onKill callback that was set. - Called the moment the tween is killed - - - Sets the onWaypointChange callback for the tween, clearing any previous onWaypointChange callback that was set. - Called when a path tween's current waypoint changes - - - Sets the parameters of the tween (id, ease, loops, delay, timeScale, callbacks, etc) as the parameters of the given one. - Doesn't copy specific SetOptions settings: those will need to be applied manually each time. - Has no effect if the tween has already started. - NOTE: the tween's target will not be changed - Tween from which to copy the parameters - - - Sets the parameters of the tween (id, ease, loops, delay, timeScale, callbacks, etc) as the parameters of the given TweenParams. - Has no effect if the tween has already started. - TweenParams from which to copy the parameters - - - Adds the given tween to the end of the Sequence. - Has no effect if the Sequence has already started - The tween to append - - - Adds the given tween to the beginning of the Sequence, pushing forward the other nested content. - Has no effect if the Sequence has already started - The tween to prepend - - - Inserts the given tween at the same time position of the last tween, callback or intervale added to the Sequence. - Note that, in case of a Join after an interval, the insertion time will be the time where the interval starts, not where it finishes. - Has no effect if the Sequence has already started - - - Inserts the given tween at the given time position in the Sequence, - automatically adding an interval if needed. - Has no effect if the Sequence has already started - The time position where the tween will be placed - The tween to insert - - - Adds the given interval to the end of the Sequence. - Has no effect if the Sequence has already started - The interval duration - - - Adds the given interval to the beginning of the Sequence, pushing forward the other nested content. - Has no effect if the Sequence has already started - The interval duration - - - Adds the given callback to the end of the Sequence. - Has no effect if the Sequence has already started - The callback to append - - - Adds the given callback to the beginning of the Sequence, pushing forward the other nested content. - Has no effect if the Sequence has already started - The callback to prepend - - - Inserts the given callback at the given time position in the Sequence, - automatically adding an interval if needed. - Has no effect if the Sequence has already started - The time position where the callback will be placed - The callback to insert - - - Changes a TO tween into a FROM tween: sets the current target's position as the tween's endValue - then immediately sends the target to the previously set endValue. - - - Changes a TO tween into a FROM tween: sets the current target's position as the tween's endValue - then immediately sends the target to the previously set endValue. - If TRUE the FROM value will be calculated as relative to the current one - - - Changes a TO tween into a FROM tween: sets the current value of the target as the endValue, - and the previously passed endValue as the actual startValue. - If TRUE sets the target to from value immediately, otherwise waits for the tween to start - If TRUE the FROM value will be calculated as relative to the current one - - - Changes a TO tween into a FROM tween: sets the tween's starting value to the given one - and eventually sets the tween's target to that value immediately. - Value to start from - If TRUE sets the target to from value immediately, otherwise waits for the tween to start - If TRUE the FROM/TO values will be calculated as relative to the current ones - - - Changes a TO tween into a FROM tween: sets the tween's starting value to the given one - and eventually sets the tween's target to that value immediately. - Alpha value to start from (in case of Fade tweens) - If TRUE sets the target to from value immediately, otherwise waits for the tween to start - If TRUE the FROM/TO values will be calculated as relative to the current ones - - - Changes a TO tween into a FROM tween: sets the tween's starting value to the given one - and eventually sets the tween's target to that value immediately. - Value to start from (in case of Vector tweens that act on a single coordinate or scale tweens) - If TRUE sets the target to from value immediately, otherwise waits for the tween to start - If TRUE the FROM/TO values will be calculated as relative to the current ones - - - Changes a TO tween into a FROM tween: sets the tween's starting value to the given one - and eventually sets the tween's target to that value immediately. - Value to start from (in case of Vector tweens that act on a single coordinate or scale tweens) - If TRUE sets the target to from value immediately, otherwise waits for the tween to start - If TRUE the FROM/TO values will be calculated as relative to the current ones - - - Sets a delayed startup for the tween. - In case of Sequences behaves the same as , - which means the delay will repeat in case of loops (while with tweens it's ignored after the first loop cycle). - Has no effect if the tween has already started - - - EXPERIMENTAL: implemented in v1.2.340. - Sets a delayed startup for the tween with options to choose how the delay is applied in case of Sequences. - Has no effect if the tween has already started - Only used by types: If FALSE sets the delay as a one-time occurrence - (defaults to this for types), - otherwise as a Sequence interval which will repeat at the beginning of every loop cycle - - - Sets the tween as relative - (the endValue will be calculated as startValue + endValue instead than being used directly). - Has no effect on Sequences or if the tween has already started - - - If isRelative is TRUE sets the tween as relative - (the endValue will be calculated as startValue + endValue instead than being used directly). - Has no effect on Sequences or if the tween has already started - - - If isSpeedBased is TRUE sets the tween as speed based - (the duration will represent the number of units the tween moves x second). - Has no effect on Sequences, nested tweens, or if the tween has already started - - - If isSpeedBased is TRUE sets the tween as speed based - (the duration will represent the number of units the tween moves x second). - Has no effect on Sequences, nested tweens, or if the tween has already started - - - Options for float tweens - If TRUE the tween will smoothly snap all values to integers - - - Options for Vector2 tweens - If TRUE the tween will smoothly snap all values to integers - - - Options for Vector2 tweens - Selecting an axis will tween the vector only on that axis, leaving the others untouched - If TRUE the tween will smoothly snap all values to integers - - - Options for Vector3 tweens - If TRUE the tween will smoothly snap all values to integers - - - Options for Vector3 tweens - Selecting an axis will tween the vector only on that axis, leaving the others untouched - If TRUE the tween will smoothly snap all values to integers - - - Options for Vector4 tweens - If TRUE the tween will smoothly snap all values to integers - - - Options for Vector4 tweens - Selecting an axis will tween the vector only on that axis, leaving the others untouched - If TRUE the tween will smoothly snap all values to integers - - - Options for Quaternion tweens - If TRUE (default) the rotation will take the shortest route, and will not rotate more than 360°. - If FALSE the rotation will be fully accounted. Is always FALSE if the tween is set as relative - - - Options for Color tweens - If TRUE only the alpha value of the color will be tweened - - - Options for Vector4 tweens - If TRUE the tween will smoothly snap all values to integers - - - Options for Vector4 tweens - If TRUE, rich text will be interpreted correctly while animated, - otherwise all tags will be considered as normal text - The type of scramble to use, if any - A string containing the characters to use for scrambling. - Use as many characters as possible (minimum 10) because DOTween uses a fast scramble mode which gives better results with more characters. - Leave it to NULL to use default ones - - - Options for Vector3Array tweens - If TRUE the tween will smoothly snap all values to integers - - - Options for Vector3Array tweens - If TRUE the tween will smoothly snap all values to integers - - - Options for ShapeCircle tweens - If TRUE the center you set in the DOTween.To method will be considered as relative - to the starting position of the target - If TRUE the tween will smoothly snap all values to integers - - - Options for Path tweens (created via the DOPath shortcut) - The eventual movement axis to lock. You can input multiple axis if you separate them like this: - AxisConstrain.X | AxisConstraint.Y - The eventual rotation axis to lock. You can input multiple axis if you separate them like this: - AxisConstrain.X | AxisConstraint.Y - - - Options for Path tweens (created via the DOPath shortcut) - If TRUE the path will be automatically closed - The eventual movement axis to lock. You can input multiple axis if you separate them like this: - AxisConstrain.X | AxisConstraint.Y - The eventual rotation axis to lock. You can input multiple axis if you separate them like this: - AxisConstrain.X | AxisConstraint.Y - - - Additional LookAt options for Path tweens (created via the DOPath shortcut). - Orients the target towards the given position. - Must be chained directly to the tween creation method or to a SetOptions - The position to look at - The eventual direction to consider as "forward". - If left to NULL defaults to the regular forward side of the transform - The vector that defines in which direction up is (default: Vector3.up) - - - Additional LookAt options for Path tweens (created via the DOPath shortcut). - Orients the target towards the given position with options to keep the Z rotation stable. - Must be chained directly to the tween creation method or to a SetOptions - The position to look at - If TRUE doesn't rotate the target along the Z axis - - - Additional LookAt options for Path tweens (created via the DOPath shortcut). - Orients the target towards another transform. - Must be chained directly to the tween creation method or to a SetOptions - The transform to look at - The eventual direction to consider as "forward". - If left to NULL defaults to the regular forward side of the transform - The vector that defines in which direction up is (default: Vector3.up) - - - Additional LookAt options for Path tweens (created via the DOPath shortcut). - Orients the target towards another transform with options to keep the Z rotation stable. - Must be chained directly to the tween creation method or to a SetOptions - The transform to look at - If TRUE doesn't rotate the target along the Z axis - - - Additional LookAt options for Path tweens (created via the DOPath shortcut). - Orients the target to the path, with the given lookAhead. - Must be chained directly to the tween creation method or to a SetOptions - The percentage of lookAhead to use (0 to 1) - The eventual direction to consider as "forward". - If left to NULL defaults to the regular forward side of the transform - The vector that defines in which direction up is (default: Vector3.up) - - - Additional LookAt options for Path tweens (created via the DOPath shortcut). - Orients the path with options to keep the Z rotation stable. - Must be chained directly to the tween creation method or to a SetOptions - The percentage of lookAhead to use (0 to 1) - If TRUE doesn't rotate the target along the Z axis - - - - Types of log behaviours - - - - Log only warnings and errors - - - Log warnings, errors and additional infos - - - Log only errors - - - - Indicates either a Tweener or a Sequence - - - - TimeScale for the tween - - - If TRUE the tween will play backwards - - - If TRUE the tween is completely inverted but without playing it backwards - (play backwards will actually play the tween in the original direction) - - - Object ID (usable for filtering with DOTween static methods). Can be anything except a string or an int - (use or for those) - - - String ID (usable for filtering with DOTween static methods). 2X faster than using an object id - - - Int ID (usable for filtering with DOTween static methods). 4X faster than using an object id, 2X faster than using a string id. - Default is -999 so avoid using an ID like that or it will capture all unset intIds - - - Tween target (usable for filtering with DOTween static methods). Automatically set by tween creation shortcuts - - - Called when the tween is set in a playing state, after any eventual delay. - Also called each time the tween resumes playing from a paused state - - - Called when the tween state changes from playing to paused. - If the tween has autoKill set to FALSE, this is called also when the tween reaches completion. - - - Called when the tween is rewinded, - either by calling Rewind or by reaching the start position while playing backwards. - Rewinding a tween that is already rewinded will not fire this callback - - - Called each time the tween updates - - - Called the moment the tween completes one loop cycle - - - Called the moment the tween reaches completion (loops included) - - - Called the moment the tween is killed - - - Called when a path tween's current waypoint changes - - - Tweeners-only (ignored by Sequences), returns TRUE if the tween was set as relative - - - - Set by SetTarget if DOTween's Debug Mode is on (see DOTween Utility Panel -> "Store GameObject's ID" debug option - - - - FALSE when tween is (or should be) despawned - set only by TweenManager - - - Gets and sets the time position (loops included, delays excluded) of the tween - - - Returns TRUE if the tween is set to loop (either a set number of times or infinitely) - - - TRUE after the tween was set in a play state at least once, AFTER any delay is elapsed - - - Time position within a single loop cycle - - - - Animates a single value - - - - Changes the start value of a tween and rewinds it (without pausing it). - Has no effect with tweens that are inside Sequences - The new start value - If bigger than 0 applies it as the new tween duration - - - Changes the end value of a tween and rewinds it (without pausing it). - Has no effect with tweens that are inside Sequences - The new end value - If bigger than 0 applies it as the new tween duration - If TRUE the start value will become the current target's value, otherwise it will stay the same - - - Changes the end value of a tween and rewinds it (without pausing it). - Has no effect with tweens that are inside Sequences - The new end value - If TRUE the start value will become the current target's value, otherwise it will stay the same - - - Changes the start and end value of a tween and rewinds it (without pausing it). - Has no effect with tweens that are inside Sequences - The new start value - The new end value - If bigger than 0 applies it as the new tween duration - - - - Used internally - - - - - Update type - - - - Updates every frame during Update calls - - - Updates every frame during LateUpdate calls - - - Updates using FixedUpdate calls - - - Updates using manual update calls - - - diff --git a/unity/Assets/Demigiant/DOTween/DOTween.XML.meta b/unity/Assets/Demigiant/DOTween/DOTween.XML.meta deleted file mode 100644 index 7a866b5..0000000 --- a/unity/Assets/Demigiant/DOTween/DOTween.XML.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 34192c5e0d14aee43a0e86cc4823268a -TextScriptImporter: - userData: diff --git a/unity/Assets/Demigiant/DOTween/DOTween.dll b/unity/Assets/Demigiant/DOTween/DOTween.dll deleted file mode 100644 index 4c0bb10614d73a5b46e58df117be2e2e2729aae0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 172032 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 ~)CFU>gFNmEmDDr()MofeLM*N!iq)bs8(sgG(U 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 CoM(&x diff --git a/unity/Assets/Demigiant/DOTween/DOTween.dll.mdb.meta b/unity/Assets/Demigiant/DOTween/DOTween.dll.mdb.meta deleted file mode 100644 index f64a22a..0000000 --- a/unity/Assets/Demigiant/DOTween/DOTween.dll.mdb.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 4f007001a22b3d24dae350342c4d19c8 -DefaultImporter: - userData: diff --git a/unity/Assets/Demigiant/DOTween/DOTween.dll.meta b/unity/Assets/Demigiant/DOTween/DOTween.dll.meta deleted file mode 100644 index 482dbb8..0000000 --- a/unity/Assets/Demigiant/DOTween/DOTween.dll.meta +++ /dev/null @@ -1,22 +0,0 @@ -fileFormatVersion: 2 -guid: a811bde74b26b53498b4f6d872b09b6d -PluginImporter: - serializedVersion: 1 - iconMap: {} - executionOrder: {} - isPreloaded: 0 - platformData: - Any: - enabled: 1 - settings: {} - Editor: - enabled: 0 - settings: - DefaultValueInitialized: true - WindowsStoreApps: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/unity/Assets/Demigiant/DOTween/Editor.meta b/unity/Assets/Demigiant/DOTween/Editor.meta deleted file mode 100644 index 532edfb..0000000 --- a/unity/Assets/Demigiant/DOTween/Editor.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: b27f58ae5d5c33a4bb2d1f4f34bd036d -folderAsset: yes -DefaultImporter: - userData: diff --git a/unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.XML b/unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.XML deleted file mode 100644 index 8b82472..0000000 --- a/unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.XML +++ /dev/null @@ -1,110 +0,0 @@ - - - - DOTweenEditor - - - - - Starts the update loop of tween in the editor. Has no effect during playMode. - - Eventual callback to call after every update - - - - Stops the update loop and clears the onPreviewUpdated callback. - - If TRUE also resets the tweened objects to their original state. - Note that this works by calling Rewind on all tweens, so it will work correctly - only if you have a single tween type per object and it wasn't killed - If TRUE also kills any cached tween - - - - Readies the tween for editor preview by setting its UpdateType to Manual plus eventual extra settings. - - The tween to ready - If TRUE (recommended) removes all callbacks (OnComplete/Rewind/etc) - If TRUE prevents the tween from being auto-killed at completion - If TRUE starts playing the tween immediately - - - Full major version + first minor version (ex: 2018.1f) - - - Major version - - - First minor version (ex: in 2018.1 it would be 1) - - - - Checks that the given editor texture use the correct import settings, - and applies them if they're incorrect. - - - - - Returns TRUE if setup is required - - - - - Returns TRUE if the file/directory at the given path exists. - - Path, relative to Unity's project folder - - - - - Converts the given project-relative path to a full path, - with backward (\) slashes). - - - - - Converts the given full path to a path usable with AssetDatabase methods - (relative to Unity's project folder, and with the correct Unity forward (/) slashes). - - - - - Connects to a asset. - If the asset already exists at the given path, loads it and returns it. - Otherwise, either returns NULL or automatically creates it before loading and returning it - (depending on the given parameters). - - Asset type - File path (relative to Unity's project folder) - If TRUE and the requested asset doesn't exist, forces its creation - - - - Full path for the given loaded assembly, assembly file included - - - - - Adds the given global define if it's not already present - - - - - Removes the given global define if it's present - - - - - Returns TRUE if the given global define is present in all the - or only in the given , depending on passed parameters. - - - to use. Leave NULL to check in all of them. - - - - Not used as menu item anymore, but as a utiity function - - - - diff --git a/unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.XML.meta b/unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.XML.meta deleted file mode 100644 index 7cec113..0000000 --- a/unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.XML.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: 2e2c6224d345d9249acfa6e8ef40bb2d -TextScriptImporter: - userData: diff --git a/unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll b/unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll deleted file mode 100644 index 1599b4066a5a958b3446e67cddd5926fc2ed7688..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66048 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 QuO7ac!T&$z|2hZ$7vfCwQUCw| diff --git a/unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll.mdb b/unity/Assets/Demigiant/DOTween/Editor/DOTweenEditor.dll.mdb deleted file mode 100644 index fa2e9032c8671017aaf1b6bc5c2175026edb576f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11774 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 P00000NkvXXu0mjftl$Bl diff --git a/unity/Assets/Demigiant/DOTween/Editor/Imgs/DOTweenIcon.png.meta b/unity/Assets/Demigiant/DOTween/Editor/Imgs/DOTweenIcon.png.meta deleted file mode 100644 index 61c3cce..0000000 --- a/unity/Assets/Demigiant/DOTween/Editor/Imgs/DOTweenIcon.png.meta +++ /dev/null @@ -1,47 +0,0 @@ -fileFormatVersion: 2 -guid: 8da095e39e9b4df488dfd436f81116d6 -TextureImporter: - fileIDToRecycleName: {} - serializedVersion: 2 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - linearTexture: 1 - correctGamma: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: .25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 0 - seamlessCubemap: 0 - textureFormat: -3 - maxTextureSize: 128 - textureSettings: - filterMode: 1 - aniso: 1 - mipBias: -1 - wrapMode: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaIsTransparency: 1 - textureType: 2 - buildTargetSettings: [] - spriteSheet: - sprites: [] - spritePackingTag: - userData: diff --git a/unity/Assets/Demigiant/DOTween/Editor/Imgs/DOTweenMiniIcon.png b/unity/Assets/Demigiant/DOTween/Editor/Imgs/DOTweenMiniIcon.png deleted file mode 100644 index 7cd74c1a26df1a45564c7a0e21c62d0ef3af2fd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 319 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{!3Opi<85sBugD~Uq{1quc!H=FU zjv*3LlT#WP(iF^Cl2R3(u|Mi}s1fft&-^joZ3WZ(2Ug1Y!S$8-a*li}_21XqSnvJ# z@Y+`2=i8W`Zfg*cV81TuZmqUr`JI~8M}9x(m1v%HMLo`ySuokJ?%Vq7{C4$+ST-HH z5`RuO<@s#=8XoVy+lF)YEaxg?4vAr1(jlM1>Tx0PF<0}pFUf679a{7Ee==}5`qQz? zuIUa#(3byge21?t-^6oqTDwHc&iz0s`zDdQwtGKbESsPtIM1KwqFB4+nW=frYn!|7 zvs(U9y->(A=TFZ3t)>6Hv^;B{u+A(fd3smW;eIaTDS0KOITHVv7#gf%Y$mkMJ`MCd NgQu&X%Q~loCICTRfS>>X diff --git a/unity/Assets/Demigiant/DOTween/Editor/Imgs/DOTweenMiniIcon.png.meta b/unity/Assets/Demigiant/DOTween/Editor/Imgs/DOTweenMiniIcon.png.meta deleted file mode 100644 index c343a61..0000000 --- a/unity/Assets/Demigiant/DOTween/Editor/Imgs/DOTweenMiniIcon.png.meta +++ /dev/null @@ -1,68 +0,0 @@ -fileFormatVersion: 2 -guid: 61521df2e071645488ba3d05e49289ae -timeCreated: 1602317874 -licenseType: Store -TextureImporter: - fileIDToRecycleName: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapMode: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/unity/Assets/Demigiant/DOTween/Editor/Imgs/Footer.png b/unity/Assets/Demigiant/DOTween/Editor/Imgs/Footer.png deleted file mode 100644 index e29d02fe18b777b1d316feb647b339803c5126de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4409 zcmV-95ytL`P)pV>q$gGRCt{2oC$Q5#TCcD7amE(Ks303SwK{(RslVzXgwBDL5mBB zO!&X`s5NnMP!d66Squ>^lr3!+A3tD$YP%)tx0ZmANge>p%_kWr1 zoyo`dUVwn{Xzn?4X1+Uj?%bKVbLY;a!agi_i&ZSdg1<+SH4z7L^2^IbYtkPC@6BgdP2+RrVpf1yb$ z0t)aOqL&%)O5%eElifT`f&&gX;0=_i4~n!7)F9$TQeM(+3IA|u=ggVY4!V584ixx^ zU@-V0w8xloH)LjJ&i1K0IV&q`1!ab!tm{FYi5%}si4DoksWz*GwB7>X=?oP>`s!aLAAk zZFn!bx&`(#G-*X(P^CO~U`-=RjS_2+FIF1Mn8Uzt$C_UzYfi{Vp}#HJSQX zpv1S3zD+dnnF^o38rf=~znkPjgbrmf|)Q!gtr(BtI>gZ{; zMOOa=X4d&44m5Sot& zwaDP@mw20m26>c^mWBUxzSq#k4#;)^s2k((X@O>hrk)zDWS}pJGD}G4=cZ+?iMpny zroPICafxE`ZvlU}^3BGz1O=HyJpcOZuis{hu7c(`l~G`y@g^JBKiAaMw6iPLMwoDh ze0qIjfz_7&rrrp^yPs9$0%Tob(pnvkbn5{B6|&uH@?ItMcKv)-jpK>z3Fw8cxGxz> zXkR3msCT)(M~@z@N&gn#6Vz8ZIXN2}@6r}%4rtPffb!hTATPxQILx5r50{y|=_tiu zeB@Ou@e7F01sz7IZ6A3W;SuP5?IQ5;A3*6}qs%fsm$QG+L|c2!HP?J@?-Mp`*dV`q zB>AhrKckH*=vr2mJeNl92z)vaCsBti^4Y>;sc%D$*U8g~&KklH!oTp}zh?r>fo~3B znf4r%)BeSGl`&98TML;m3(dq^g=|r`PKN-xYanFraR;}+4+c%Xn99q`>xfbfBw0bc z1Z6l9%NN-<$f}}H7oh}4p)6~Qii#H4KE14YWo6}QvdT73od{88pjHp~eeCAT;wC00 zp6-5Y6@Y&~=zhuPrzqeemp@AUA^1O1Z%4U0gn3eQw+<#x8hM&zZK>lO@?LlIjNF%? z#OdTc2VH06e8*a~qCBAa1^K1$*M-;`+PK6%>YX}uYFGN@?b_Pfj;s(dCzMXh;Bk(P zgZGtAy>YSOKIlHN5%7OX$I`KQw?O0YgWk~okf4cxBK@JcHkLXzEiEl=FSiakDlrZ> z#G{XKv%Fi-aHj~H}!P~AA${(SQ+f+9Q0zYH&`Y1zMn4;U_y0u)w{W zvwqz!6Se-K>t(NUC{ZT+Al-`V1gu#1Gd^@(ph@xKb+fM+mp6;@x+MJ;+_yFjuIoWe z?krZjZLGLo+VpODFQh(EcyMB(b3z~-NDd`9r70C{K3YHg?5I1ZLkW1+YA6UM{4S4+1c3*jGNmIUA}rU zV(|AdAs(~nCPUNLhegC)W;MH?NSBI*go|tf6z?v|-UJWb&YvP2$~2z320I>iJ8j;J z8LdO1hr*7dePqxHgq;LFDpR&c%Nlu>!b9#|g9n>gSy{dHDnRM2Tel7(ns4XpwjNpf zP`6$+T<797fy^DuBVD?58DCRV)8IbF!(&sB4WA0PvG5gym;J2B-T?e>q2p#TTerlc zW3aMyj*o@;BpzLydXA>NPG&mm-4hmKnf-o9FGUsai#>y$mSDVgVEvZa=|;*Ni%h*( zsb=kNJ+$LV$}IHYbZZ{dx*1r9OlK*<{-GNKeHZ0&>4T26|4y3_{@wjqIB8D(y-Odg zeH+`_qF{PgrGtZARumgL%zdeIC{*`0dfz7C1n#K|I15_`oXvHiaC$fpd1linP|t6P zbYYpScVmucBDg^NMzaD;@mrCSlatGK?%Wxj^zd1%H*ADk_00sV4#MDWJue_$Z|HO; z{wRty21S~%JHo~T_+Cv#&ytKg5rENznS?!_2uvbfRE;P6+nlJh*Rdsdo!wt18r^6c z@+MCNCiWF{rmWX8`2LEtPNSAJQl_(>VvwA*yY+WPM6EfGm2^Yk2W$3?lx~n1Chsh)(QfTV$2|kPD^Mqb;riiN5I?-U92}_^z%W)=j#x{>mC7m9pF-@Ghs06N-?CAj;*%m(;%_pUB}bbg@a&Ar%)1y}(MhL-Vu)HOnr zmv{^oQBN|?HV*?G@b@e1Nqf9?V;Ohx`Kjx6!bC6LOH17gvBrbqwPk;SQ3U<2A%O{b zNn`W^bU^!q&(VV-(wAFVN^4)Rp3u&(tU#+l*ooW^6>e@g33eNBi!`>nm0ye;FQ~rl z+qa(^gIsUQPQ`#A`-lk}}xDk~}~ z2Jv0V_k-lgLTmPwFjIT$&5mAu>ZK-h$Cw9t52Hl)c@vhe0mRXmXs#B9d25YjOyA!|YAx$wCxN>zS8LY{oH%!2xZQHhOuQYz%6h9%U?-cU?d2A>D-_SNDG+Vk7GR{3Ia|SuFzL zP=$+PgFL`#-KxY5Tbz_L?3L$_(ZLWRw$yU-EYc0i%i$r1(4*sw25S+#GE2gQP$Y0pp( zuFKvqLf#CMY~Y{Eb@kGkG0@mo)YR0x5)1~bwZFkYX)jblU#!f?$mpRJhH+NE?Q)q% zkCxTPflL<{3I~?4jPwOLz_Ctv{J?k*+KX(nRxQ<)M%`x+@8WJT&T|=?8))l|=vZz% z{$7Z=BGB-oi8e$U5DIl=*RAIhYOs#rx_Vw{ZtxT@_u(hY5yUc0a04BwRiW5JrzKgN z_-kD{aQd~_3b{-^qJC+fSVW+zs_H%D?5n`%B4ee!vK)uicomuw_&y5Fu^y6*7Of`q z7W-+4TnHaIqVmMa+f$IS>E;P>Pio>or-QzLk<+1zULk9B zC~K@97knpz-q0Y(g|em*qJ)H5M1^uASf+F=_mrnd{NFM<^_@yoRa8`TJ~Owk0{k_5 zAMwzsgY}&IMwbq&q*Y_Q`!h@%;4z12m^(@28|oy)oQC+GRKa_$RvEcyY7c2|du;xi zWom0LsV?j8#tKt`kF&InJ(bU`&Wubqb!y zQu3YBD2bLM{mN?t9zW(s|097z%-$=NzK|QCbN^z-;7Ttc zefFUJO*``_6EP~#NBW4eIy%*>-fi^vayL)zVYvP`-@d@Aa9u*M)k)AibXY-QKR7K$ z*{Ynd(?6c@dZ_5s9}z!puf#h2Vl1?AzDg&Wa#MZl4TZ*<{Y6^5dTdCbfX>}7L~-PT z=-xmK^4aWN?4AbbIWy5HDwj(jf9)?cZlhKXD&0nYgKKfa)4e{IWvnp__E7qt%Y|7|`YBw+&_9_E5J5t~-<9JDrFT^n84yX={<2HZGIB3fa7N z;k%ze&mj(^uGxe;v^OBW6W6u}W3b*O0$(ax?ZxZ>Z3n0Rf>n7D7grlqt)P5QvlLTf z^{q}3^`T2lQ+E`!DpUt+x-(sL*pd#Be%i~#3u{w8x0O>DJyxguW}=8OX8g_*FK`9k z#z|*Pp8H#qQd2ex+FV07*0iC*%frZ7Y9sy+?8Q2{9e}yQ00000NkvXXu0mjfzsHtQ diff --git a/unity/Assets/Demigiant/DOTween/Editor/Imgs/Footer.png.meta b/unity/Assets/Demigiant/DOTween/Editor/Imgs/Footer.png.meta deleted file mode 100644 index 7ca1911..0000000 --- a/unity/Assets/Demigiant/DOTween/Editor/Imgs/Footer.png.meta +++ /dev/null @@ -1,47 +0,0 @@ -fileFormatVersion: 2 -guid: 7051dba417b3d53409f2918f1ea4938d -TextureImporter: - fileIDToRecycleName: {} - serializedVersion: 2 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - linearTexture: 1 - correctGamma: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: .25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 0 - seamlessCubemap: 0 - textureFormat: -3 - maxTextureSize: 256 - textureSettings: - filterMode: 1 - aniso: 1 - mipBias: -1 - wrapMode: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaIsTransparency: 1 - textureType: 2 - buildTargetSettings: [] - spriteSheet: - sprites: [] - spritePackingTag: - userData: diff --git a/unity/Assets/Demigiant/DOTween/Editor/Imgs/Footer_dark.png b/unity/Assets/Demigiant/DOTween/Editor/Imgs/Footer_dark.png deleted file mode 100644 index e48db5ef7a2b83eff50d6e3b5fe9ba3bcd4a5015..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4429 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 TqmFO~00000NkvXXu0mjf{EM6C diff --git a/unity/Assets/Demigiant/DOTween/Editor/Imgs/Footer_dark.png.meta b/unity/Assets/Demigiant/DOTween/Editor/Imgs/Footer_dark.png.meta deleted file mode 100644 index f12a1a7..0000000 --- a/unity/Assets/Demigiant/DOTween/Editor/Imgs/Footer_dark.png.meta +++ /dev/null @@ -1,47 +0,0 @@ -fileFormatVersion: 2 -guid: 519694efe2bb2914788b151fbd8c01f4 -TextureImporter: - fileIDToRecycleName: {} - serializedVersion: 2 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - linearTexture: 0 - correctGamma: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: .25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 0 - seamlessCubemap: 0 - textureFormat: -1 - maxTextureSize: 1024 - textureSettings: - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapMode: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaIsTransparency: 0 - textureType: -1 - buildTargetSettings: [] - spriteSheet: - sprites: [] - spritePackingTag: - userData: diff --git a/unity/Assets/Demigiant/DOTween/Editor/Imgs/Header.jpg b/unity/Assets/Demigiant/DOTween/Editor/Imgs/Header.jpg deleted file mode 100644 index 4d710d719075150879b1ee76680af87791c4d3b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22787 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 QE#Li`lK-oJv9mh=KQ4fgsQ>@~ diff --git a/unity/Assets/Demigiant/DOTween/Editor/Imgs/Header.jpg.meta b/unity/Assets/Demigiant/DOTween/Editor/Imgs/Header.jpg.meta deleted file mode 100644 index 26e4255..0000000 --- a/unity/Assets/Demigiant/DOTween/Editor/Imgs/Header.jpg.meta +++ /dev/null @@ -1,47 +0,0 @@ -fileFormatVersion: 2 -guid: 78a59ca99f8987941adb61f9e14a06a7 -TextureImporter: - fileIDToRecycleName: {} - serializedVersion: 2 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - linearTexture: 1 - correctGamma: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: .25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 0 - seamlessCubemap: 0 - textureFormat: -3 - maxTextureSize: 512 - textureSettings: - filterMode: 1 - aniso: 1 - mipBias: -1 - wrapMode: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - alphaIsTransparency: 1 - textureType: 2 - buildTargetSettings: [] - spriteSheet: - sprites: [] - spritePackingTag: - userData: diff --git a/unity/Assets/Demigiant/DOTween/Modules.meta b/unity/Assets/Demigiant/DOTween/Modules.meta deleted file mode 100644 index 24cd2ac..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules.meta +++ /dev/null @@ -1,5 +0,0 @@ -fileFormatVersion: 2 -guid: 143604b8bad857d47a6f7cc7a533e2dc -folderAsset: yes -DefaultImporter: - userData: diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleAudio.cs b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleAudio.cs deleted file mode 100644 index c195b6c..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleAudio.cs +++ /dev/null @@ -1,202 +0,0 @@ -// Author: Daniele Giardini - http://www.demigiant.com -// Created: 2018/07/13 - -#if true // MODULE_MARKER -using System; -using DG.Tweening.Core; -using DG.Tweening.Plugins.Options; -using UnityEngine; -#if UNITY_5 || UNITY_2017_1_OR_NEWER -using UnityEngine.Audio; // Required for AudioMixer -#endif - -#pragma warning disable 1591 -namespace DG.Tweening -{ - public static class DOTweenModuleAudio - { - #region Shortcuts - - #region Audio - - /// Tweens an AudioSource's volume to the given value. - /// Also stores the AudioSource as the tween's target so it can be used for filtered operations - /// The end value to reach (0 to 1)The duration of the tween - public static TweenerCore DOFade(this AudioSource target, float endValue, float duration) - { - if (endValue < 0) endValue = 0; - else if (endValue > 1) endValue = 1; - TweenerCore t = DOTween.To(() => target.volume, x => target.volume = x, endValue, duration); - t.SetTarget(target); - return t; - } - - /// Tweens an AudioSource's pitch to the given value. - /// Also stores the AudioSource as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOPitch(this AudioSource target, float endValue, float duration) - { - TweenerCore t = DOTween.To(() => target.pitch, x => target.pitch = x, endValue, duration); - t.SetTarget(target); - return t; - } - - #endregion - -#if UNITY_5 || UNITY_2017_1_OR_NEWER - #region AudioMixer (Unity 5 or Newer) - - /// Tweens an AudioMixer's exposed float to the given value. - /// Also stores the AudioMixer as the tween's target so it can be used for filtered operations. - /// Note that you need to manually expose a float in an AudioMixerGroup in order to be able to tween it from an AudioMixer. - /// Name given to the exposed float to set - /// The end value to reachThe duration of the tween - public static TweenerCore DOSetFloat(this AudioMixer target, string floatName, float endValue, float duration) - { - TweenerCore t = DOTween.To(()=> { - float currVal; - target.GetFloat(floatName, out currVal); - return currVal; - }, x=> target.SetFloat(floatName, x), endValue, duration); - t.SetTarget(target); - return t; - } - - #region Operation Shortcuts - - /// - /// Completes all tweens that have this target as a reference - /// (meaning tweens that were started from this target, or that had this target added as an Id) - /// and returns the total number of tweens completed - /// (meaning the tweens that don't have infinite loops and were not already complete) - /// - /// For Sequences only: if TRUE also internal Sequence callbacks will be fired, - /// otherwise they will be ignored - public static int DOComplete(this AudioMixer target, bool withCallbacks = false) - { - return DOTween.Complete(target, withCallbacks); - } - - /// - /// Kills all tweens that have this target as a reference - /// (meaning tweens that were started from this target, or that had this target added as an Id) - /// and returns the total number of tweens killed. - /// - /// If TRUE completes the tween before killing it - public static int DOKill(this AudioMixer target, bool complete = false) - { - return DOTween.Kill(target, complete); - } - - /// - /// Flips the direction (backwards if it was going forward or viceversa) of all tweens that have this target as a reference - /// (meaning tweens that were started from this target, or that had this target added as an Id) - /// and returns the total number of tweens flipped. - /// - public static int DOFlip(this AudioMixer target) - { - return DOTween.Flip(target); - } - - /// - /// Sends to the given position all tweens that have this target as a reference - /// (meaning tweens that were started from this target, or that had this target added as an Id) - /// and returns the total number of tweens involved. - /// - /// Time position to reach - /// (if higher than the whole tween duration the tween will simply reach its end) - /// If TRUE will play the tween after reaching the given position, otherwise it will pause it - public static int DOGoto(this AudioMixer target, float to, bool andPlay = false) - { - return DOTween.Goto(target, to, andPlay); - } - - /// - /// Pauses all tweens that have this target as a reference - /// (meaning tweens that were started from this target, or that had this target added as an Id) - /// and returns the total number of tweens paused. - /// - public static int DOPause(this AudioMixer target) - { - return DOTween.Pause(target); - } - - /// - /// Plays all tweens that have this target as a reference - /// (meaning tweens that were started from this target, or that had this target added as an Id) - /// and returns the total number of tweens played. - /// - public static int DOPlay(this AudioMixer target) - { - return DOTween.Play(target); - } - - /// - /// Plays backwards all tweens that have this target as a reference - /// (meaning tweens that were started from this target, or that had this target added as an Id) - /// and returns the total number of tweens played. - /// - public static int DOPlayBackwards(this AudioMixer target) - { - return DOTween.PlayBackwards(target); - } - - /// - /// Plays forward all tweens that have this target as a reference - /// (meaning tweens that were started from this target, or that had this target added as an Id) - /// and returns the total number of tweens played. - /// - public static int DOPlayForward(this AudioMixer target) - { - return DOTween.PlayForward(target); - } - - /// - /// Restarts all tweens that have this target as a reference - /// (meaning tweens that were started from this target, or that had this target added as an Id) - /// and returns the total number of tweens restarted. - /// - public static int DORestart(this AudioMixer target) - { - return DOTween.Restart(target); - } - - /// - /// Rewinds all tweens that have this target as a reference - /// (meaning tweens that were started from this target, or that had this target added as an Id) - /// and returns the total number of tweens rewinded. - /// - public static int DORewind(this AudioMixer target) - { - return DOTween.Rewind(target); - } - - /// - /// Smoothly rewinds all tweens that have this target as a reference - /// (meaning tweens that were started from this target, or that had this target added as an Id) - /// and returns the total number of tweens rewinded. - /// - public static int DOSmoothRewind(this AudioMixer target) - { - return DOTween.SmoothRewind(target); - } - - /// - /// Toggles the paused state (plays if it was paused, pauses if it was playing) of all tweens that have this target as a reference - /// (meaning tweens that were started from this target, or that had this target added as an Id) - /// and returns the total number of tweens involved. - /// - public static int DOTogglePause(this AudioMixer target) - { - return DOTween.TogglePause(target); - } - - #endregion - - #endregion -#endif - - #endregion - } -} -#endif diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleAudio.cs.meta b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleAudio.cs.meta deleted file mode 100644 index 50aa010..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleAudio.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b766d08851589514b97afb23c6f30a70 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleEPOOutline.cs b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleEPOOutline.cs deleted file mode 100644 index aff1235..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleEPOOutline.cs +++ /dev/null @@ -1,142 +0,0 @@ -using UnityEngine; - -#if false || EPO_DOTWEEN // MODULE_MARKER - -using EPOOutline; -using DG.Tweening.Plugins.Options; -using DG.Tweening; -using DG.Tweening.Core; - -namespace DG.Tweening -{ - public static class DOTweenModuleEPOOutline - { - public static int DOKill(this SerializedPass target, bool complete) - { - return DOTween.Kill(target, complete); - } - - public static TweenerCore DOFloat(this SerializedPass target, string propertyName, float endValue, float duration) - { - var tweener = DOTween.To(() => target.GetFloat(propertyName), x => target.SetFloat(propertyName, x), endValue, duration); - tweener.SetOptions(true).SetTarget(target); - return tweener; - } - - public static TweenerCore DOFade(this SerializedPass target, string propertyName, float endValue, float duration) - { - var tweener = DOTween.ToAlpha(() => target.GetColor(propertyName), x => target.SetColor(propertyName, x), endValue, duration); - tweener.SetOptions(true).SetTarget(target); - return tweener; - } - - public static TweenerCore DOColor(this SerializedPass target, string propertyName, Color endValue, float duration) - { - var tweener = DOTween.To(() => target.GetColor(propertyName), x => target.SetColor(propertyName, x), endValue, duration); - tweener.SetOptions(false).SetTarget(target); - return tweener; - } - - public static TweenerCore DOVector(this SerializedPass target, string propertyName, Vector4 endValue, float duration) - { - var tweener = DOTween.To(() => target.GetVector(propertyName), x => target.SetVector(propertyName, x), endValue, duration); - tweener.SetOptions(false).SetTarget(target); - return tweener; - } - - public static TweenerCore DOFloat(this SerializedPass target, int propertyId, float endValue, float duration) - { - var tweener = DOTween.To(() => target.GetFloat(propertyId), x => target.SetFloat(propertyId, x), endValue, duration); - tweener.SetOptions(true).SetTarget(target); - return tweener; - } - - public static TweenerCore DOFade(this SerializedPass target, int propertyId, float endValue, float duration) - { - var tweener = DOTween.ToAlpha(() => target.GetColor(propertyId), x => target.SetColor(propertyId, x), endValue, duration); - tweener.SetOptions(true).SetTarget(target); - return tweener; - } - - public static TweenerCore DOColor(this SerializedPass target, int propertyId, Color endValue, float duration) - { - var tweener = DOTween.To(() => target.GetColor(propertyId), x => target.SetColor(propertyId, x), endValue, duration); - tweener.SetOptions(false).SetTarget(target); - return tweener; - } - - public static TweenerCore DOVector(this SerializedPass target, int propertyId, Vector4 endValue, float duration) - { - var tweener = DOTween.To(() => target.GetVector(propertyId), x => target.SetVector(propertyId, x), endValue, duration); - tweener.SetOptions(false).SetTarget(target); - return tweener; - } - - public static int DOKill(this Outlinable.OutlineProperties target, bool complete = false) - { - return DOTween.Kill(target, complete); - } - - public static int DOKill(this Outliner target, bool complete = false) - { - return DOTween.Kill(target, complete); - } - - public static TweenerCore DOFade(this Outlinable.OutlineProperties target, float endValue, float duration) - { - var tweener = DOTween.ToAlpha(() => target.Color, x => target.Color = x, endValue, duration); - tweener.SetOptions(true).SetTarget(target); - return tweener; - } - - public static TweenerCore DOColor(this Outlinable.OutlineProperties target, Color endValue, float duration) - { - var tweener = DOTween.To(() => target.Color, x => target.Color = x, endValue, duration); - tweener.SetOptions(false).SetTarget(target); - return tweener; - } - - public static TweenerCore DODilateShift(this Outlinable.OutlineProperties target, float endValue, float duration, bool snapping = false) - { - var tweener = DOTween.To(() => target.DilateShift, x => target.DilateShift = x, endValue, duration); - tweener.SetOptions(snapping).SetTarget(target); - return tweener; - } - - public static TweenerCore DOBlurShift(this Outlinable.OutlineProperties target, float endValue, float duration, bool snapping = false) - { - var tweener = DOTween.To(() => target.BlurShift, x => target.BlurShift = x, endValue, duration); - tweener.SetOptions(snapping).SetTarget(target); - return tweener; - } - - public static TweenerCore DOBlurShift(this Outliner target, float endValue, float duration, bool snapping = false) - { - var tweener = DOTween.To(() => target.BlurShift, x => target.BlurShift = x, endValue, duration); - tweener.SetOptions(snapping).SetTarget(target); - return tweener; - } - - public static TweenerCore DODilateShift(this Outliner target, float endValue, float duration, bool snapping = false) - { - var tweener = DOTween.To(() => target.DilateShift, x => target.DilateShift = x, endValue, duration); - tweener.SetOptions(snapping).SetTarget(target); - return tweener; - } - - public static TweenerCore DOInfoRendererScale(this Outliner target, float endValue, float duration, bool snapping = false) - { - var tweener = DOTween.To(() => target.InfoRendererScale, x => target.InfoRendererScale = x, endValue, duration); - tweener.SetOptions(snapping).SetTarget(target); - return tweener; - } - - public static TweenerCore DOPrimaryRendererScale(this Outliner target, float endValue, float duration, bool snapping = false) - { - var tweener = DOTween.To(() => target.PrimaryRendererScale, x => target.PrimaryRendererScale = x, endValue, duration); - tweener.SetOptions(snapping).SetTarget(target); - return tweener; - } - } -} -#endif diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleEPOOutline.cs.meta b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleEPOOutline.cs.meta deleted file mode 100644 index 4b8991f..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleEPOOutline.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: e944529dcaee98f4e9498d80e541d93e -timeCreated: 1602593330 -licenseType: Store -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics.cs b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics.cs deleted file mode 100644 index 08b0700..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics.cs +++ /dev/null @@ -1,216 +0,0 @@ -// Author: Daniele Giardini - http://www.demigiant.com -// Created: 2018/07/13 - -#if true // MODULE_MARKER -using System; -using DG.Tweening.Core; -using DG.Tweening.Core.Enums; -using DG.Tweening.Plugins; -using DG.Tweening.Plugins.Core.PathCore; -using DG.Tweening.Plugins.Options; -using UnityEngine; - -#pragma warning disable 1591 -namespace DG.Tweening -{ - public static class DOTweenModulePhysics - { - #region Shortcuts - - #region Rigidbody - - /// Tweens a Rigidbody's position to the given value. - /// Also stores the rigidbody as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOMove(this Rigidbody target, Vector3 endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.position, target.MovePosition, endValue, duration); - t.SetOptions(snapping).SetTarget(target); - return t; - } - - /// Tweens a Rigidbody's X position to the given value. - /// Also stores the rigidbody as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOMoveX(this Rigidbody target, float endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.position, target.MovePosition, new Vector3(endValue, 0, 0), duration); - t.SetOptions(AxisConstraint.X, snapping).SetTarget(target); - return t; - } - - /// Tweens a Rigidbody's Y position to the given value. - /// Also stores the rigidbody as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOMoveY(this Rigidbody target, float endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.position, target.MovePosition, new Vector3(0, endValue, 0), duration); - t.SetOptions(AxisConstraint.Y, snapping).SetTarget(target); - return t; - } - - /// Tweens a Rigidbody's Z position to the given value. - /// Also stores the rigidbody as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOMoveZ(this Rigidbody target, float endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.position, target.MovePosition, new Vector3(0, 0, endValue), duration); - t.SetOptions(AxisConstraint.Z, snapping).SetTarget(target); - return t; - } - - /// Tweens a Rigidbody's rotation to the given value. - /// Also stores the rigidbody as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// Rotation mode - public static TweenerCore DORotate(this Rigidbody target, Vector3 endValue, float duration, RotateMode mode = RotateMode.Fast) - { - TweenerCore t = DOTween.To(() => target.rotation, target.MoveRotation, endValue, duration); - t.SetTarget(target); - t.plugOptions.rotateMode = mode; - return t; - } - - /// Tweens a Rigidbody's rotation so that it will look towards the given position. - /// Also stores the rigidbody as the tween's target so it can be used for filtered operations - /// The position to look atThe duration of the tween - /// Eventual axis constraint for the rotation - /// The vector that defines in which direction up is (default: Vector3.up) - public static TweenerCore DOLookAt(this Rigidbody target, Vector3 towards, float duration, AxisConstraint axisConstraint = AxisConstraint.None, Vector3? up = null) - { - TweenerCore t = DOTween.To(() => target.rotation, target.MoveRotation, towards, duration) - .SetTarget(target).SetSpecialStartupMode(SpecialStartupMode.SetLookAt); - t.plugOptions.axisConstraint = axisConstraint; - t.plugOptions.up = (up == null) ? Vector3.up : (Vector3)up; - return t; - } - - #region Special - - /// Tweens a Rigidbody's position to the given value, while also applying a jump effect along the Y axis. - /// Returns a Sequence instead of a Tweener. - /// Also stores the Rigidbody as the tween's target so it can be used for filtered operations - /// The end value to reach - /// Power of the jump (the max height of the jump is represented by this plus the final Y offset) - /// Total number of jumps - /// The duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static Sequence DOJump(this Rigidbody target, Vector3 endValue, float jumpPower, int numJumps, float duration, bool snapping = false) - { - if (numJumps < 1) numJumps = 1; - float startPosY = 0; - float offsetY = -1; - bool offsetYSet = false; - Sequence s = DOTween.Sequence(); - Tween yTween = DOTween.To(() => target.position, target.MovePosition, new Vector3(0, jumpPower, 0), duration / (numJumps * 2)) - .SetOptions(AxisConstraint.Y, snapping).SetEase(Ease.OutQuad).SetRelative() - .SetLoops(numJumps * 2, LoopType.Yoyo) - .OnStart(() => startPosY = target.position.y); - s.Append(DOTween.To(() => target.position, target.MovePosition, new Vector3(endValue.x, 0, 0), duration) - .SetOptions(AxisConstraint.X, snapping).SetEase(Ease.Linear) - ).Join(DOTween.To(() => target.position, target.MovePosition, new Vector3(0, 0, endValue.z), duration) - .SetOptions(AxisConstraint.Z, snapping).SetEase(Ease.Linear) - ).Join(yTween) - .SetTarget(target).SetEase(DOTween.defaultEaseType); - yTween.OnUpdate(() => { - if (!offsetYSet) { - offsetYSet = true; - offsetY = s.isRelative ? endValue.y : endValue.y - startPosY; - } - Vector3 pos = target.position; - pos.y += DOVirtual.EasedValue(0, offsetY, yTween.ElapsedPercentage(), Ease.OutQuad); - target.MovePosition(pos); - }); - return s; - } - - /// Tweens a Rigidbody's position through the given path waypoints, using the chosen path algorithm. - /// Also stores the Rigidbody as the tween's target so it can be used for filtered operations. - /// NOTE: to tween a rigidbody correctly it should be set to kinematic at least while being tweened. - /// BEWARE: doesn't work on Windows Phone store (waiting for Unity to fix their own bug). - /// If you plan to publish there you should use a regular transform.DOPath. - /// The waypoints to go through - /// The duration of the tween - /// The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points) - /// The path mode: 3D, side-scroller 2D, top-down 2D - /// The resolution of the path (useless in case of Linear paths): higher resolutions make for more detailed curved paths but are more expensive. - /// Defaults to 10, but a value of 5 is usually enough if you don't have dramatic long curves between waypoints - /// The color of the path (shown when gizmos are active in the Play panel and the tween is running) - public static TweenerCore DOPath( - this Rigidbody target, Vector3[] path, float duration, PathType pathType = PathType.Linear, - PathMode pathMode = PathMode.Full3D, int resolution = 10, Color? gizmoColor = null - ) - { - if (resolution < 1) resolution = 1; - TweenerCore t = DOTween.To(PathPlugin.Get(), () => target.position, target.MovePosition, new Path(pathType, path, resolution, gizmoColor), duration) - .SetTarget(target).SetUpdate(UpdateType.Fixed); - - t.plugOptions.isRigidbody = true; - t.plugOptions.mode = pathMode; - return t; - } - /// Tweens a Rigidbody's localPosition through the given path waypoints, using the chosen path algorithm. - /// Also stores the Rigidbody as the tween's target so it can be used for filtered operations - /// NOTE: to tween a rigidbody correctly it should be set to kinematic at least while being tweened. - /// BEWARE: doesn't work on Windows Phone store (waiting for Unity to fix their own bug). - /// If you plan to publish there you should use a regular transform.DOLocalPath. - /// The waypoint to go through - /// The duration of the tween - /// The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points) - /// The path mode: 3D, side-scroller 2D, top-down 2D - /// The resolution of the path: higher resolutions make for more detailed curved paths but are more expensive. - /// Defaults to 10, but a value of 5 is usually enough if you don't have dramatic long curves between waypoints - /// The color of the path (shown when gizmos are active in the Play panel and the tween is running) - public static TweenerCore DOLocalPath( - this Rigidbody target, Vector3[] path, float duration, PathType pathType = PathType.Linear, - PathMode pathMode = PathMode.Full3D, int resolution = 10, Color? gizmoColor = null - ) - { - if (resolution < 1) resolution = 1; - Transform trans = target.transform; - TweenerCore t = DOTween.To(PathPlugin.Get(), () => trans.localPosition, x => target.MovePosition(trans.parent == null ? x : trans.parent.TransformPoint(x)), new Path(pathType, path, resolution, gizmoColor), duration) - .SetTarget(target).SetUpdate(UpdateType.Fixed); - - t.plugOptions.isRigidbody = true; - t.plugOptions.mode = pathMode; - t.plugOptions.useLocalPosition = true; - return t; - } - // Used by path editor when creating the actual tween, so it can pass a pre-compiled path - internal static TweenerCore DOPath( - this Rigidbody target, Path path, float duration, PathMode pathMode = PathMode.Full3D - ) - { - TweenerCore t = DOTween.To(PathPlugin.Get(), () => target.position, target.MovePosition, path, duration) - .SetTarget(target); - - t.plugOptions.isRigidbody = true; - t.plugOptions.mode = pathMode; - return t; - } - internal static TweenerCore DOLocalPath( - this Rigidbody target, Path path, float duration, PathMode pathMode = PathMode.Full3D - ) - { - Transform trans = target.transform; - TweenerCore t = DOTween.To(PathPlugin.Get(), () => trans.localPosition, x => target.MovePosition(trans.parent == null ? x : trans.parent.TransformPoint(x)), path, duration) - .SetTarget(target); - - t.plugOptions.isRigidbody = true; - t.plugOptions.mode = pathMode; - t.plugOptions.useLocalPosition = true; - return t; - } - - #endregion - - #endregion - - #endregion - } -} -#endif diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics.cs.meta b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics.cs.meta deleted file mode 100644 index 0ce0d75..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: dae9aa560b4242648a3affa2bfabc365 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics2D.cs b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics2D.cs deleted file mode 100644 index d01f728..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics2D.cs +++ /dev/null @@ -1,193 +0,0 @@ -// Author: Daniele Giardini - http://www.demigiant.com -// Created: 2018/07/13 - -#if true && (UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_5 || UNITY_2017_1_OR_NEWER) // MODULE_MARKER -using System; -using DG.Tweening.Core; -using DG.Tweening.Plugins; -using DG.Tweening.Plugins.Core.PathCore; -using DG.Tweening.Plugins.Options; -using UnityEngine; - -#pragma warning disable 1591 -namespace DG.Tweening -{ - public static class DOTweenModulePhysics2D - { - #region Shortcuts - - #region Rigidbody2D Shortcuts - - /// Tweens a Rigidbody2D's position to the given value. - /// Also stores the Rigidbody2D as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOMove(this Rigidbody2D target, Vector2 endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.position, target.MovePosition, endValue, duration); - t.SetOptions(snapping).SetTarget(target); - return t; - } - - /// Tweens a Rigidbody2D's X position to the given value. - /// Also stores the Rigidbody2D as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOMoveX(this Rigidbody2D target, float endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.position, target.MovePosition, new Vector2(endValue, 0), duration); - t.SetOptions(AxisConstraint.X, snapping).SetTarget(target); - return t; - } - - /// Tweens a Rigidbody2D's Y position to the given value. - /// Also stores the Rigidbody2D as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOMoveY(this Rigidbody2D target, float endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.position, target.MovePosition, new Vector2(0, endValue), duration); - t.SetOptions(AxisConstraint.Y, snapping).SetTarget(target); - return t; - } - - /// Tweens a Rigidbody2D's rotation to the given value. - /// Also stores the Rigidbody2D as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DORotate(this Rigidbody2D target, float endValue, float duration) - { - TweenerCore t = DOTween.To(() => target.rotation, target.MoveRotation, endValue, duration); - t.SetTarget(target); - return t; - } - - #region Special - - /// Tweens a Rigidbody2D's position to the given value, while also applying a jump effect along the Y axis. - /// Returns a Sequence instead of a Tweener. - /// Also stores the Rigidbody2D as the tween's target so it can be used for filtered operations. - /// IMPORTANT: a rigidbody2D can't be animated in a jump arc using MovePosition, so the tween will directly set the position - /// The end value to reach - /// Power of the jump (the max height of the jump is represented by this plus the final Y offset) - /// Total number of jumps - /// The duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static Sequence DOJump(this Rigidbody2D target, Vector2 endValue, float jumpPower, int numJumps, float duration, bool snapping = false) - { - if (numJumps < 1) numJumps = 1; - float startPosY = 0; - float offsetY = -1; - bool offsetYSet = false; - Sequence s = DOTween.Sequence(); - Tween yTween = DOTween.To(() => target.position, x => target.position = x, new Vector2(0, jumpPower), duration / (numJumps * 2)) - .SetOptions(AxisConstraint.Y, snapping).SetEase(Ease.OutQuad).SetRelative() - .SetLoops(numJumps * 2, LoopType.Yoyo) - .OnStart(() => startPosY = target.position.y); - s.Append(DOTween.To(() => target.position, x => target.position = x, new Vector2(endValue.x, 0), duration) - .SetOptions(AxisConstraint.X, snapping).SetEase(Ease.Linear) - ).Join(yTween) - .SetTarget(target).SetEase(DOTween.defaultEaseType); - yTween.OnUpdate(() => { - if (!offsetYSet) { - offsetYSet = true; - offsetY = s.isRelative ? endValue.y : endValue.y - startPosY; - } - Vector3 pos = target.position; - pos.y += DOVirtual.EasedValue(0, offsetY, yTween.ElapsedPercentage(), Ease.OutQuad); - target.MovePosition(pos); - }); - return s; - } - - /// Tweens a Rigidbody2D's position through the given path waypoints, using the chosen path algorithm. - /// Also stores the Rigidbody2D as the tween's target so it can be used for filtered operations. - /// NOTE: to tween a Rigidbody2D correctly it should be set to kinematic at least while being tweened. - /// BEWARE: doesn't work on Windows Phone store (waiting for Unity to fix their own bug). - /// If you plan to publish there you should use a regular transform.DOPath. - /// The waypoints to go through - /// The duration of the tween - /// The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points) - /// The path mode: 3D, side-scroller 2D, top-down 2D - /// The resolution of the path (useless in case of Linear paths): higher resolutions make for more detailed curved paths but are more expensive. - /// Defaults to 10, but a value of 5 is usually enough if you don't have dramatic long curves between waypoints - /// The color of the path (shown when gizmos are active in the Play panel and the tween is running) - public static TweenerCore DOPath( - this Rigidbody2D target, Vector2[] path, float duration, PathType pathType = PathType.Linear, - PathMode pathMode = PathMode.Full3D, int resolution = 10, Color? gizmoColor = null - ) - { - if (resolution < 1) resolution = 1; - int len = path.Length; - Vector3[] path3D = new Vector3[len]; - for (int i = 0; i < len; ++i) path3D[i] = path[i]; - TweenerCore t = DOTween.To(PathPlugin.Get(), () => target.position, x => target.MovePosition(x), new Path(pathType, path3D, resolution, gizmoColor), duration) - .SetTarget(target).SetUpdate(UpdateType.Fixed); - - t.plugOptions.isRigidbody2D = true; - t.plugOptions.mode = pathMode; - return t; - } - /// Tweens a Rigidbody2D's localPosition through the given path waypoints, using the chosen path algorithm. - /// Also stores the Rigidbody2D as the tween's target so it can be used for filtered operations - /// NOTE: to tween a Rigidbody2D correctly it should be set to kinematic at least while being tweened. - /// BEWARE: doesn't work on Windows Phone store (waiting for Unity to fix their own bug). - /// If you plan to publish there you should use a regular transform.DOLocalPath. - /// The waypoint to go through - /// The duration of the tween - /// The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points) - /// The path mode: 3D, side-scroller 2D, top-down 2D - /// The resolution of the path: higher resolutions make for more detailed curved paths but are more expensive. - /// Defaults to 10, but a value of 5 is usually enough if you don't have dramatic long curves between waypoints - /// The color of the path (shown when gizmos are active in the Play panel and the tween is running) - public static TweenerCore DOLocalPath( - this Rigidbody2D target, Vector2[] path, float duration, PathType pathType = PathType.Linear, - PathMode pathMode = PathMode.Full3D, int resolution = 10, Color? gizmoColor = null - ) - { - if (resolution < 1) resolution = 1; - int len = path.Length; - Vector3[] path3D = new Vector3[len]; - for (int i = 0; i < len; ++i) path3D[i] = path[i]; - Transform trans = target.transform; - TweenerCore t = DOTween.To(PathPlugin.Get(), () => trans.localPosition, x => target.MovePosition(trans.parent == null ? x : trans.parent.TransformPoint(x)), new Path(pathType, path3D, resolution, gizmoColor), duration) - .SetTarget(target).SetUpdate(UpdateType.Fixed); - - t.plugOptions.isRigidbody2D = true; - t.plugOptions.mode = pathMode; - t.plugOptions.useLocalPosition = true; - return t; - } - // Used by path editor when creating the actual tween, so it can pass a pre-compiled path - internal static TweenerCore DOPath( - this Rigidbody2D target, Path path, float duration, PathMode pathMode = PathMode.Full3D - ) - { - TweenerCore t = DOTween.To(PathPlugin.Get(), () => target.position, x => target.MovePosition(x), path, duration) - .SetTarget(target); - - t.plugOptions.isRigidbody2D = true; - t.plugOptions.mode = pathMode; - return t; - } - internal static TweenerCore DOLocalPath( - this Rigidbody2D target, Path path, float duration, PathMode pathMode = PathMode.Full3D - ) - { - Transform trans = target.transform; - TweenerCore t = DOTween.To(PathPlugin.Get(), () => trans.localPosition, x => target.MovePosition(trans.parent == null ? x : trans.parent.TransformPoint(x)), path, duration) - .SetTarget(target); - - t.plugOptions.isRigidbody2D = true; - t.plugOptions.mode = pathMode; - t.plugOptions.useLocalPosition = true; - return t; - } - - #endregion - - #endregion - - #endregion - } -} -#endif diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics2D.cs.meta b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics2D.cs.meta deleted file mode 100644 index ca9ed29..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModulePhysics2D.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 230fe34542e175245ba74b4659dae700 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleSprite.cs b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleSprite.cs deleted file mode 100644 index 549fff3..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleSprite.cs +++ /dev/null @@ -1,93 +0,0 @@ -// Author: Daniele Giardini - http://www.demigiant.com -// Created: 2018/07/13 - -#if true && (UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_5 || UNITY_2017_1_OR_NEWER) // MODULE_MARKER -using System; -using UnityEngine; -using DG.Tweening.Core; -using DG.Tweening.Plugins.Options; - -#pragma warning disable 1591 -namespace DG.Tweening -{ - public static class DOTweenModuleSprite - { - #region Shortcuts - - #region SpriteRenderer - - /// Tweens a SpriteRenderer's color to the given value. - /// Also stores the spriteRenderer as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOColor(this SpriteRenderer target, Color endValue, float duration) - { - TweenerCore t = DOTween.To(() => target.color, x => target.color = x, endValue, duration); - t.SetTarget(target); - return t; - } - - /// Tweens a Material's alpha color to the given value. - /// Also stores the spriteRenderer as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOFade(this SpriteRenderer target, float endValue, float duration) - { - TweenerCore t = DOTween.ToAlpha(() => target.color, x => target.color = x, endValue, duration); - t.SetTarget(target); - return t; - } - - /// Tweens a SpriteRenderer's color using the given gradient - /// (NOTE 1: only uses the colors of the gradient, not the alphas - NOTE 2: creates a Sequence, not a Tweener). - /// Also stores the image as the tween's target so it can be used for filtered operations - /// The gradient to useThe duration of the tween - public static Sequence DOGradientColor(this SpriteRenderer target, Gradient gradient, float duration) - { - Sequence s = DOTween.Sequence(); - GradientColorKey[] colors = gradient.colorKeys; - int len = colors.Length; - for (int i = 0; i < len; ++i) { - GradientColorKey c = colors[i]; - if (i == 0 && c.time <= 0) { - target.color = c.color; - continue; - } - float colorDuration = i == len - 1 - ? duration - s.Duration(false) // Verifies that total duration is correct - : duration * (i == 0 ? c.time : c.time - colors[i - 1].time); - s.Append(target.DOColor(c.color, colorDuration).SetEase(Ease.Linear)); - } - s.SetTarget(target); - return s; - } - - #endregion - - #region Blendables - - #region SpriteRenderer - - /// Tweens a SpriteRenderer's color to the given value, - /// in a way that allows other DOBlendableColor tweens to work together on the same target, - /// instead than fight each other as multiple DOColor would do. - /// Also stores the SpriteRenderer as the tween's target so it can be used for filtered operations - /// The value to tween toThe duration of the tween - public static Tweener DOBlendableColor(this SpriteRenderer target, Color endValue, float duration) - { - endValue = endValue - target.color; - Color to = new Color(0, 0, 0, 0); - return DOTween.To(() => to, x => { - Color diff = x - to; - to = x; - target.color += diff; - }, endValue, duration) - .Blendable().SetTarget(target); - } - - #endregion - - #endregion - - #endregion - } -} -#endif diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleSprite.cs.meta b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleSprite.cs.meta deleted file mode 100644 index a0c67c4..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleSprite.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 188918ab119d93148aa0de59ccf5286b -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUI.cs b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUI.cs deleted file mode 100644 index dc24ebf..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUI.cs +++ /dev/null @@ -1,660 +0,0 @@ -// Author: Daniele Giardini - http://www.demigiant.com -// Created: 2018/07/13 - -#if true && (UNITY_4_6 || UNITY_5 || UNITY_2017_1_OR_NEWER) // MODULE_MARKER - -using System; -using System.Globalization; -using UnityEngine; -using UnityEngine.UI; -using DG.Tweening.Core; -using DG.Tweening.Core.Enums; -using DG.Tweening.Plugins; -using DG.Tweening.Plugins.Options; -using Outline = UnityEngine.UI.Outline; -using Text = UnityEngine.UI.Text; - -#pragma warning disable 1591 -namespace DG.Tweening -{ - public static class DOTweenModuleUI - { - #region Shortcuts - - #region CanvasGroup - - /// Tweens a CanvasGroup's alpha color to the given value. - /// Also stores the canvasGroup as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOFade(this CanvasGroup target, float endValue, float duration) - { - TweenerCore t = DOTween.To(() => target.alpha, x => target.alpha = x, endValue, duration); - t.SetTarget(target); - return t; - } - - #endregion - - #region Graphic - - /// Tweens an Graphic's color to the given value. - /// Also stores the image as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOColor(this Graphic target, Color endValue, float duration) - { - TweenerCore t = DOTween.To(() => target.color, x => target.color = x, endValue, duration); - t.SetTarget(target); - return t; - } - - /// Tweens an Graphic's alpha color to the given value. - /// Also stores the image as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOFade(this Graphic target, float endValue, float duration) - { - TweenerCore t = DOTween.ToAlpha(() => target.color, x => target.color = x, endValue, duration); - t.SetTarget(target); - return t; - } - - #endregion - - #region Image - - /// Tweens an Image's color to the given value. - /// Also stores the image as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOColor(this Image target, Color endValue, float duration) - { - TweenerCore t = DOTween.To(() => target.color, x => target.color = x, endValue, duration); - t.SetTarget(target); - return t; - } - - /// Tweens an Image's alpha color to the given value. - /// Also stores the image as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOFade(this Image target, float endValue, float duration) - { - TweenerCore t = DOTween.ToAlpha(() => target.color, x => target.color = x, endValue, duration); - t.SetTarget(target); - return t; - } - - /// Tweens an Image's fillAmount to the given value. - /// Also stores the image as the tween's target so it can be used for filtered operations - /// The end value to reach (0 to 1)The duration of the tween - public static TweenerCore DOFillAmount(this Image target, float endValue, float duration) - { - if (endValue > 1) endValue = 1; - else if (endValue < 0) endValue = 0; - TweenerCore t = DOTween.To(() => target.fillAmount, x => target.fillAmount = x, endValue, duration); - t.SetTarget(target); - return t; - } - - /// Tweens an Image's colors using the given gradient - /// (NOTE 1: only uses the colors of the gradient, not the alphas - NOTE 2: creates a Sequence, not a Tweener). - /// Also stores the image as the tween's target so it can be used for filtered operations - /// The gradient to useThe duration of the tween - public static Sequence DOGradientColor(this Image target, Gradient gradient, float duration) - { - Sequence s = DOTween.Sequence(); - GradientColorKey[] colors = gradient.colorKeys; - int len = colors.Length; - for (int i = 0; i < len; ++i) { - GradientColorKey c = colors[i]; - if (i == 0 && c.time <= 0) { - target.color = c.color; - continue; - } - float colorDuration = i == len - 1 - ? duration - s.Duration(false) // Verifies that total duration is correct - : duration * (i == 0 ? c.time : c.time - colors[i - 1].time); - s.Append(target.DOColor(c.color, colorDuration).SetEase(Ease.Linear)); - } - s.SetTarget(target); - return s; - } - - #endregion - - #region LayoutElement - - /// Tweens an LayoutElement's flexibleWidth/Height to the given value. - /// Also stores the LayoutElement as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOFlexibleSize(this LayoutElement target, Vector2 endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => new Vector2(target.flexibleWidth, target.flexibleHeight), x => { - target.flexibleWidth = x.x; - target.flexibleHeight = x.y; - }, endValue, duration); - t.SetOptions(snapping).SetTarget(target); - return t; - } - - /// Tweens an LayoutElement's minWidth/Height to the given value. - /// Also stores the LayoutElement as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOMinSize(this LayoutElement target, Vector2 endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => new Vector2(target.minWidth, target.minHeight), x => { - target.minWidth = x.x; - target.minHeight = x.y; - }, endValue, duration); - t.SetOptions(snapping).SetTarget(target); - return t; - } - - /// Tweens an LayoutElement's preferredWidth/Height to the given value. - /// Also stores the LayoutElement as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOPreferredSize(this LayoutElement target, Vector2 endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => new Vector2(target.preferredWidth, target.preferredHeight), x => { - target.preferredWidth = x.x; - target.preferredHeight = x.y; - }, endValue, duration); - t.SetOptions(snapping).SetTarget(target); - return t; - } - - #endregion - - #region Outline - - /// Tweens a Outline's effectColor to the given value. - /// Also stores the Outline as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOColor(this Outline target, Color endValue, float duration) - { - TweenerCore t = DOTween.To(() => target.effectColor, x => target.effectColor = x, endValue, duration); - t.SetTarget(target); - return t; - } - - /// Tweens a Outline's effectColor alpha to the given value. - /// Also stores the Outline as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOFade(this Outline target, float endValue, float duration) - { - TweenerCore t = DOTween.ToAlpha(() => target.effectColor, x => target.effectColor = x, endValue, duration); - t.SetTarget(target); - return t; - } - - /// Tweens a Outline's effectDistance to the given value. - /// Also stores the Outline as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOScale(this Outline target, Vector2 endValue, float duration) - { - TweenerCore t = DOTween.To(() => target.effectDistance, x => target.effectDistance = x, endValue, duration); - t.SetTarget(target); - return t; - } - - #endregion - - #region RectTransform - - /// Tweens a RectTransform's anchoredPosition to the given value. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOAnchorPos(this RectTransform target, Vector2 endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, endValue, duration); - t.SetOptions(snapping).SetTarget(target); - return t; - } - /// Tweens a RectTransform's anchoredPosition X to the given value. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOAnchorPosX(this RectTransform target, float endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, new Vector2(endValue, 0), duration); - t.SetOptions(AxisConstraint.X, snapping).SetTarget(target); - return t; - } - /// Tweens a RectTransform's anchoredPosition Y to the given value. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOAnchorPosY(this RectTransform target, float endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, new Vector2(0, endValue), duration); - t.SetOptions(AxisConstraint.Y, snapping).SetTarget(target); - return t; - } - - /// Tweens a RectTransform's anchoredPosition3D to the given value. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOAnchorPos3D(this RectTransform target, Vector3 endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.anchoredPosition3D, x => target.anchoredPosition3D = x, endValue, duration); - t.SetOptions(snapping).SetTarget(target); - return t; - } - /// Tweens a RectTransform's anchoredPosition3D X to the given value. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOAnchorPos3DX(this RectTransform target, float endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.anchoredPosition3D, x => target.anchoredPosition3D = x, new Vector3(endValue, 0, 0), duration); - t.SetOptions(AxisConstraint.X, snapping).SetTarget(target); - return t; - } - /// Tweens a RectTransform's anchoredPosition3D Y to the given value. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOAnchorPos3DY(this RectTransform target, float endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.anchoredPosition3D, x => target.anchoredPosition3D = x, new Vector3(0, endValue, 0), duration); - t.SetOptions(AxisConstraint.Y, snapping).SetTarget(target); - return t; - } - /// Tweens a RectTransform's anchoredPosition3D Z to the given value. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOAnchorPos3DZ(this RectTransform target, float endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.anchoredPosition3D, x => target.anchoredPosition3D = x, new Vector3(0, 0, endValue), duration); - t.SetOptions(AxisConstraint.Z, snapping).SetTarget(target); - return t; - } - - /// Tweens a RectTransform's anchorMax to the given value. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOAnchorMax(this RectTransform target, Vector2 endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.anchorMax, x => target.anchorMax = x, endValue, duration); - t.SetOptions(snapping).SetTarget(target); - return t; - } - - /// Tweens a RectTransform's anchorMin to the given value. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOAnchorMin(this RectTransform target, Vector2 endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.anchorMin, x => target.anchorMin = x, endValue, duration); - t.SetOptions(snapping).SetTarget(target); - return t; - } - - /// Tweens a RectTransform's pivot to the given value. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOPivot(this RectTransform target, Vector2 endValue, float duration) - { - TweenerCore t = DOTween.To(() => target.pivot, x => target.pivot = x, endValue, duration); - t.SetTarget(target); - return t; - } - /// Tweens a RectTransform's pivot X to the given value. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOPivotX(this RectTransform target, float endValue, float duration) - { - TweenerCore t = DOTween.To(() => target.pivot, x => target.pivot = x, new Vector2(endValue, 0), duration); - t.SetOptions(AxisConstraint.X).SetTarget(target); - return t; - } - /// Tweens a RectTransform's pivot Y to the given value. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOPivotY(this RectTransform target, float endValue, float duration) - { - TweenerCore t = DOTween.To(() => target.pivot, x => target.pivot = x, new Vector2(0, endValue), duration); - t.SetOptions(AxisConstraint.Y).SetTarget(target); - return t; - } - - /// Tweens a RectTransform's sizeDelta to the given value. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOSizeDelta(this RectTransform target, Vector2 endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.sizeDelta, x => target.sizeDelta = x, endValue, duration); - t.SetOptions(snapping).SetTarget(target); - return t; - } - - /// Punches a RectTransform's anchoredPosition towards the given direction and then back to the starting one - /// as if it was connected to the starting position via an elastic. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The direction and strength of the punch (added to the RectTransform's current position) - /// The duration of the tween - /// Indicates how much will the punch vibrate - /// Represents how much (0 to 1) the vector will go beyond the starting position when bouncing backwards. - /// 1 creates a full oscillation between the punch direction and the opposite direction, - /// while 0 oscillates only between the punch and the start position - /// If TRUE the tween will smoothly snap all values to integers - public static Tweener DOPunchAnchorPos(this RectTransform target, Vector2 punch, float duration, int vibrato = 10, float elasticity = 1, bool snapping = false) - { - return DOTween.Punch(() => target.anchoredPosition, x => target.anchoredPosition = x, punch, duration, vibrato, elasticity) - .SetTarget(target).SetOptions(snapping); - } - - /// Shakes a RectTransform's anchoredPosition with the given values. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The duration of the tween - /// The shake strength - /// Indicates how much will the shake vibrate - /// Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). - /// Setting it to 0 will shake along a single direction. - /// If TRUE the tween will smoothly snap all values to integers - /// If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not - public static Tweener DOShakeAnchorPos(this RectTransform target, float duration, float strength = 100, int vibrato = 10, float randomness = 90, bool snapping = false, bool fadeOut = true) - { - return DOTween.Shake(() => target.anchoredPosition, x => target.anchoredPosition = x, duration, strength, vibrato, randomness, true, fadeOut) - .SetTarget(target).SetSpecialStartupMode(SpecialStartupMode.SetShake).SetOptions(snapping); - } - /// Shakes a RectTransform's anchoredPosition with the given values. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The duration of the tween - /// The shake strength on each axis - /// Indicates how much will the shake vibrate - /// Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware). - /// Setting it to 0 will shake along a single direction. - /// If TRUE the tween will smoothly snap all values to integers - /// If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not - public static Tweener DOShakeAnchorPos(this RectTransform target, float duration, Vector2 strength, int vibrato = 10, float randomness = 90, bool snapping = false, bool fadeOut = true) - { - return DOTween.Shake(() => target.anchoredPosition, x => target.anchoredPosition = x, duration, strength, vibrato, randomness, fadeOut) - .SetTarget(target).SetSpecialStartupMode(SpecialStartupMode.SetShake).SetOptions(snapping); - } - - #region Special - - /// Tweens a RectTransform's anchoredPosition to the given value, while also applying a jump effect along the Y axis. - /// Returns a Sequence instead of a Tweener. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations - /// The end value to reach - /// Power of the jump (the max height of the jump is represented by this plus the final Y offset) - /// Total number of jumps - /// The duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static Sequence DOJumpAnchorPos(this RectTransform target, Vector2 endValue, float jumpPower, int numJumps, float duration, bool snapping = false) - { - if (numJumps < 1) numJumps = 1; - float startPosY = 0; - float offsetY = -1; - bool offsetYSet = false; - - // Separate Y Tween so we can elaborate elapsedPercentage on that insted of on the Sequence - // (in case users add a delay or other elements to the Sequence) - Sequence s = DOTween.Sequence(); - Tween yTween = DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, new Vector2(0, jumpPower), duration / (numJumps * 2)) - .SetOptions(AxisConstraint.Y, snapping).SetEase(Ease.OutQuad).SetRelative() - .SetLoops(numJumps * 2, LoopType.Yoyo) - .OnStart(()=> startPosY = target.anchoredPosition.y); - s.Append(DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, new Vector2(endValue.x, 0), duration) - .SetOptions(AxisConstraint.X, snapping).SetEase(Ease.Linear) - ).Join(yTween) - .SetTarget(target).SetEase(DOTween.defaultEaseType); - s.OnUpdate(() => { - if (!offsetYSet) { - offsetYSet = true; - offsetY = s.isRelative ? endValue.y : endValue.y - startPosY; - } - Vector2 pos = target.anchoredPosition; - pos.y += DOVirtual.EasedValue(0, offsetY, s.ElapsedDirectionalPercentage(), Ease.OutQuad); - target.anchoredPosition = pos; - }); - return s; - } - - #endregion - - #endregion - - #region ScrollRect - - /// Tweens a ScrollRect's horizontal/verticalNormalizedPosition to the given value. - /// Also stores the ScrollRect as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static Tweener DONormalizedPos(this ScrollRect target, Vector2 endValue, float duration, bool snapping = false) - { - return DOTween.To(() => new Vector2(target.horizontalNormalizedPosition, target.verticalNormalizedPosition), - x => { - target.horizontalNormalizedPosition = x.x; - target.verticalNormalizedPosition = x.y; - }, endValue, duration) - .SetOptions(snapping).SetTarget(target); - } - /// Tweens a ScrollRect's horizontalNormalizedPosition to the given value. - /// Also stores the ScrollRect as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static Tweener DOHorizontalNormalizedPos(this ScrollRect target, float endValue, float duration, bool snapping = false) - { - return DOTween.To(() => target.horizontalNormalizedPosition, x => target.horizontalNormalizedPosition = x, endValue, duration) - .SetOptions(snapping).SetTarget(target); - } - /// Tweens a ScrollRect's verticalNormalizedPosition to the given value. - /// Also stores the ScrollRect as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static Tweener DOVerticalNormalizedPos(this ScrollRect target, float endValue, float duration, bool snapping = false) - { - return DOTween.To(() => target.verticalNormalizedPosition, x => target.verticalNormalizedPosition = x, endValue, duration) - .SetOptions(snapping).SetTarget(target); - } - - #endregion - - #region Slider - - /// Tweens a Slider's value to the given value. - /// Also stores the Slider as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOValue(this Slider target, float endValue, float duration, bool snapping = false) - { - TweenerCore t = DOTween.To(() => target.value, x => target.value = x, endValue, duration); - t.SetOptions(snapping).SetTarget(target); - return t; - } - - #endregion - - #region Text - - /// Tweens a Text's color to the given value. - /// Also stores the Text as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOColor(this Text target, Color endValue, float duration) - { - TweenerCore t = DOTween.To(() => target.color, x => target.color = x, endValue, duration); - t.SetTarget(target); - return t; - } - - /// - /// Tweens a Text's text from one integer to another, with options for thousands separators - /// - /// The value to start from - /// The end value to reach - /// The duration of the tween - /// If TRUE (default) also adds thousands separators - /// The to use (InvariantCulture if NULL) - public static TweenerCore DOCounter( - this Text target, int fromValue, int endValue, float duration, bool addThousandsSeparator = true, CultureInfo culture = null - ){ - int v = fromValue; - CultureInfo cInfo = !addThousandsSeparator ? null : culture ?? CultureInfo.InvariantCulture; - TweenerCore t = DOTween.To(() => v, x => { - v = x; - target.text = addThousandsSeparator - ? v.ToString("N0", cInfo) - : v.ToString(); - }, endValue, duration); - t.SetTarget(target); - return t; - } - - /// Tweens a Text's alpha color to the given value. - /// Also stores the Text as the tween's target so it can be used for filtered operations - /// The end value to reachThe duration of the tween - public static TweenerCore DOFade(this Text target, float endValue, float duration) - { - TweenerCore t = DOTween.ToAlpha(() => target.color, x => target.color = x, endValue, duration); - t.SetTarget(target); - return t; - } - - /// Tweens a Text's text to the given value. - /// Also stores the Text as the tween's target so it can be used for filtered operations - /// The end string to tween toThe duration of the tween - /// If TRUE (default), rich text will be interpreted correctly while animated, - /// otherwise all tags will be considered as normal text - /// The type of scramble mode to use, if any - /// A string containing the characters to use for scrambling. - /// Use as many characters as possible (minimum 10) because DOTween uses a fast scramble mode which gives better results with more characters. - /// Leave it to NULL (default) to use default ones - public static TweenerCore DOText(this Text target, string endValue, float duration, bool richTextEnabled = true, ScrambleMode scrambleMode = ScrambleMode.None, string scrambleChars = null) - { - if (endValue == null) { - if (Debugger.logPriority > 0) Debugger.LogWarning("You can't pass a NULL string to DOText: an empty string will be used instead to avoid errors"); - endValue = ""; - } - TweenerCore t = DOTween.To(() => target.text, x => target.text = x, endValue, duration); - t.SetOptions(richTextEnabled, scrambleMode, scrambleChars) - .SetTarget(target); - return t; - } - - #endregion - - #region Blendables - - #region Graphic - - /// Tweens a Graphic's color to the given value, - /// in a way that allows other DOBlendableColor tweens to work together on the same target, - /// instead than fight each other as multiple DOColor would do. - /// Also stores the Graphic as the tween's target so it can be used for filtered operations - /// The value to tween toThe duration of the tween - public static Tweener DOBlendableColor(this Graphic target, Color endValue, float duration) - { - endValue = endValue - target.color; - Color to = new Color(0, 0, 0, 0); - return DOTween.To(() => to, x => { - Color diff = x - to; - to = x; - target.color += diff; - }, endValue, duration) - .Blendable().SetTarget(target); - } - - #endregion - - #region Image - - /// Tweens a Image's color to the given value, - /// in a way that allows other DOBlendableColor tweens to work together on the same target, - /// instead than fight each other as multiple DOColor would do. - /// Also stores the Image as the tween's target so it can be used for filtered operations - /// The value to tween toThe duration of the tween - public static Tweener DOBlendableColor(this Image target, Color endValue, float duration) - { - endValue = endValue - target.color; - Color to = new Color(0, 0, 0, 0); - return DOTween.To(() => to, x => { - Color diff = x - to; - to = x; - target.color += diff; - }, endValue, duration) - .Blendable().SetTarget(target); - } - - #endregion - - #region Text - - /// Tweens a Text's color BY the given value, - /// in a way that allows other DOBlendableColor tweens to work together on the same target, - /// instead than fight each other as multiple DOColor would do. - /// Also stores the Text as the tween's target so it can be used for filtered operations - /// The value to tween toThe duration of the tween - public static Tweener DOBlendableColor(this Text target, Color endValue, float duration) - { - endValue = endValue - target.color; - Color to = new Color(0, 0, 0, 0); - return DOTween.To(() => to, x => { - Color diff = x - to; - to = x; - target.color += diff; - }, endValue, duration) - .Blendable().SetTarget(target); - } - - #endregion - - #endregion - - #region Shapes - - /// Tweens a RectTransform's anchoredPosition so that it draws a circle around the given center. - /// Also stores the RectTransform as the tween's target so it can be used for filtered operations. - /// IMPORTANT: SetFrom(value) requires a instead of a float, where the X property represents the "from degrees value" - /// Circle-center/pivot around which to rotate (in UI anchoredPosition coordinates) - /// The end value degrees to reach (to rotate counter-clockwise pass a negative value) - /// The duration of the tween - /// If TRUE the coordinates will be considered as relative to the target's current anchoredPosition - /// If TRUE the tween will smoothly snap all values to integers - public static TweenerCore DOShapeCircle( - this RectTransform target, Vector2 center, float endValueDegrees, float duration, bool relativeCenter = false, bool snapping = false - ) - { - TweenerCore t = DOTween.To( - CirclePlugin.Get(), () => target.anchoredPosition, x => target.anchoredPosition = x, center, duration - ); - t.SetOptions(endValueDegrees, relativeCenter, snapping).SetTarget(target); - return t; - } - - #endregion - - #endregion - - // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ - // ███ INTERNAL CLASSES ████████████████████████████████████████████████████████████████████████████████████████████████ - // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ - - public static class Utils - { - /// - /// Converts the anchoredPosition of the first RectTransform to the second RectTransform, - /// taking into consideration offset, anchors and pivot, and returns the new anchoredPosition - /// - public static Vector2 SwitchToRectTransform(RectTransform from, RectTransform to) - { - Vector2 localPoint; - Vector2 fromPivotDerivedOffset = new Vector2(from.rect.width * 0.5f + from.rect.xMin, from.rect.height * 0.5f + from.rect.yMin); - Vector2 screenP = RectTransformUtility.WorldToScreenPoint(null, from.position); - screenP += fromPivotDerivedOffset; - RectTransformUtility.ScreenPointToLocalPointInRectangle(to, screenP, null, out localPoint); - Vector2 pivotDerivedOffset = new Vector2(to.rect.width * 0.5f + to.rect.xMin, to.rect.height * 0.5f + to.rect.yMin); - return to.anchoredPosition + localPoint - pivotDerivedOffset; - } - } - } -} -#endif diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUI.cs.meta b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUI.cs.meta deleted file mode 100644 index 60d55ef..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUI.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a060394c03331a64392db53a10e7f2d1 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUnityVersion.cs b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUnityVersion.cs deleted file mode 100644 index fa1ac05..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUnityVersion.cs +++ /dev/null @@ -1,403 +0,0 @@ -// Author: Daniele Giardini - http://www.demigiant.com -// Created: 2018/07/13 - -using System; -using UnityEngine; -using DG.Tweening.Core; -using DG.Tweening.Plugins.Options; -//#if UNITY_2018_1_OR_NEWER && (NET_4_6 || NET_STANDARD_2_0) -//using Task = System.Threading.Tasks.Task; -//#endif - -#pragma warning disable 1591 -namespace DG.Tweening -{ - /// - /// Shortcuts/functions that are not strictly related to specific Modules - /// but are available only on some Unity versions - /// - public static class DOTweenModuleUnityVersion - { -#if UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_5 || UNITY_2017_1_OR_NEWER - #region Unity 4.3 or Newer - - #region Material - - /// Tweens a Material's color using the given gradient - /// (NOTE 1: only uses the colors of the gradient, not the alphas - NOTE 2: creates a Sequence, not a Tweener). - /// Also stores the image as the tween's target so it can be used for filtered operations - /// The gradient to useThe duration of the tween - public static Sequence DOGradientColor(this Material target, Gradient gradient, float duration) - { - Sequence s = DOTween.Sequence(); - GradientColorKey[] colors = gradient.colorKeys; - int len = colors.Length; - for (int i = 0; i < len; ++i) { - GradientColorKey c = colors[i]; - if (i == 0 && c.time <= 0) { - target.color = c.color; - continue; - } - float colorDuration = i == len - 1 - ? duration - s.Duration(false) // Verifies that total duration is correct - : duration * (i == 0 ? c.time : c.time - colors[i - 1].time); - s.Append(target.DOColor(c.color, colorDuration).SetEase(Ease.Linear)); - } - s.SetTarget(target); - return s; - } - /// Tweens a Material's named color property using the given gradient - /// (NOTE 1: only uses the colors of the gradient, not the alphas - NOTE 2: creates a Sequence, not a Tweener). - /// Also stores the image as the tween's target so it can be used for filtered operations - /// The gradient to use - /// The name of the material property to tween (like _Tint or _SpecColor) - /// The duration of the tween - public static Sequence DOGradientColor(this Material target, Gradient gradient, string property, float duration) - { - Sequence s = DOTween.Sequence(); - GradientColorKey[] colors = gradient.colorKeys; - int len = colors.Length; - for (int i = 0; i < len; ++i) { - GradientColorKey c = colors[i]; - if (i == 0 && c.time <= 0) { - target.SetColor(property, c.color); - continue; - } - float colorDuration = i == len - 1 - ? duration - s.Duration(false) // Verifies that total duration is correct - : duration * (i == 0 ? c.time : c.time - colors[i - 1].time); - s.Append(target.DOColor(c.color, property, colorDuration).SetEase(Ease.Linear)); - } - s.SetTarget(target); - return s; - } - - #endregion - - #endregion -#endif - -#if UNITY_5_3_OR_NEWER || UNITY_2017_1_OR_NEWER - #region Unity 5.3 or Newer - - #region CustomYieldInstructions - - /// - /// Returns a that waits until the tween is killed or complete. - /// It can be used inside a coroutine as a yield. - /// Example usage:yield return myTween.WaitForCompletion(true); - /// - public static CustomYieldInstruction WaitForCompletion(this Tween t, bool returnCustomYieldInstruction) - { - if (!t.active) { - if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t); - return null; - } - return new DOTweenCYInstruction.WaitForCompletion(t); - } - - /// - /// Returns a that waits until the tween is killed or rewinded. - /// It can be used inside a coroutine as a yield. - /// Example usage:yield return myTween.WaitForRewind(); - /// - public static CustomYieldInstruction WaitForRewind(this Tween t, bool returnCustomYieldInstruction) - { - if (!t.active) { - if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t); - return null; - } - return new DOTweenCYInstruction.WaitForRewind(t); - } - - /// - /// Returns a that waits until the tween is killed. - /// It can be used inside a coroutine as a yield. - /// Example usage:yield return myTween.WaitForKill(); - /// - public static CustomYieldInstruction WaitForKill(this Tween t, bool returnCustomYieldInstruction) - { - if (!t.active) { - if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t); - return null; - } - return new DOTweenCYInstruction.WaitForKill(t); - } - - /// - /// Returns a that waits until the tween is killed or has gone through the given amount of loops. - /// It can be used inside a coroutine as a yield. - /// Example usage:yield return myTween.WaitForElapsedLoops(2); - /// - /// Elapsed loops to wait for - public static CustomYieldInstruction WaitForElapsedLoops(this Tween t, int elapsedLoops, bool returnCustomYieldInstruction) - { - if (!t.active) { - if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t); - return null; - } - return new DOTweenCYInstruction.WaitForElapsedLoops(t, elapsedLoops); - } - - /// - /// Returns a that waits until the tween is killed - /// or has reached the given time position (loops included, delays excluded). - /// It can be used inside a coroutine as a yield. - /// Example usage:yield return myTween.WaitForPosition(2.5f); - /// - /// Position (loops included, delays excluded) to wait for - public static CustomYieldInstruction WaitForPosition(this Tween t, float position, bool returnCustomYieldInstruction) - { - if (!t.active) { - if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t); - return null; - } - return new DOTweenCYInstruction.WaitForPosition(t, position); - } - - /// - /// Returns a that waits until the tween is killed or started - /// (meaning when the tween is set in a playing state the first time, after any eventual delay). - /// It can be used inside a coroutine as a yield. - /// Example usage:yield return myTween.WaitForStart(); - /// - public static CustomYieldInstruction WaitForStart(this Tween t, bool returnCustomYieldInstruction) - { - if (!t.active) { - if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t); - return null; - } - return new DOTweenCYInstruction.WaitForStart(t); - } - - #endregion - - #endregion -#endif - -#if UNITY_2018_1_OR_NEWER - #region Unity 2018.1 or Newer - - #region Material - - /// Tweens a Material's named texture offset property with the given ID to the given value. - /// Also stores the material as the tween's target so it can be used for filtered operations - /// The end value to reach - /// The ID of the material property to tween (also called nameID in Unity's manual) - /// The duration of the tween - public static TweenerCore DOOffset(this Material target, Vector2 endValue, int propertyID, float duration) - { - if (!target.HasProperty(propertyID)) { - if (Debugger.logPriority > 0) Debugger.LogMissingMaterialProperty(propertyID); - return null; - } - TweenerCore t = DOTween.To(() => target.GetTextureOffset(propertyID), x => target.SetTextureOffset(propertyID, x), endValue, duration); - t.SetTarget(target); - return t; - } - - /// Tweens a Material's named texture scale property with the given ID to the given value. - /// Also stores the material as the tween's target so it can be used for filtered operations - /// The end value to reach - /// The ID of the material property to tween (also called nameID in Unity's manual) - /// The duration of the tween - public static TweenerCore DOTiling(this Material target, Vector2 endValue, int propertyID, float duration) - { - if (!target.HasProperty(propertyID)) { - if (Debugger.logPriority > 0) Debugger.LogMissingMaterialProperty(propertyID); - return null; - } - TweenerCore t = DOTween.To(() => target.GetTextureScale(propertyID), x => target.SetTextureScale(propertyID, x), endValue, duration); - t.SetTarget(target); - return t; - } - - #endregion - - #region .NET 4.6 or Newer - -#if UNITY_2018_1_OR_NEWER && (NET_4_6 || NET_STANDARD_2_0) - - #region Async Instructions - - /// - /// Returns an async that waits until the tween is killed or complete. - /// It can be used inside an async operation. - /// Example usage:await myTween.WaitForCompletion(); - /// - public static async System.Threading.Tasks.Task AsyncWaitForCompletion(this Tween t) - { - if (!t.active) { - if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t); - return; - } - while (t.active && !t.IsComplete()) await System.Threading.Tasks.Task.Yield(); - } - - /// - /// Returns an async that waits until the tween is killed or rewinded. - /// It can be used inside an async operation. - /// Example usage:await myTween.AsyncWaitForRewind(); - /// - public static async System.Threading.Tasks.Task AsyncWaitForRewind(this Tween t) - { - if (!t.active) { - if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t); - return; - } - while (t.active && (!t.playedOnce || t.position * (t.CompletedLoops() + 1) > 0)) await System.Threading.Tasks.Task.Yield(); - } - - /// - /// Returns an async that waits until the tween is killed. - /// It can be used inside an async operation. - /// Example usage:await myTween.AsyncWaitForKill(); - /// - public static async System.Threading.Tasks.Task AsyncWaitForKill(this Tween t) - { - if (!t.active) { - if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t); - return; - } - while (t.active) await System.Threading.Tasks.Task.Yield(); - } - - /// - /// Returns an async that waits until the tween is killed or has gone through the given amount of loops. - /// It can be used inside an async operation. - /// Example usage:await myTween.AsyncWaitForElapsedLoops(); - /// - /// Elapsed loops to wait for - public static async System.Threading.Tasks.Task AsyncWaitForElapsedLoops(this Tween t, int elapsedLoops) - { - if (!t.active) { - if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t); - return; - } - while (t.active && t.CompletedLoops() < elapsedLoops) await System.Threading.Tasks.Task.Yield(); - } - - /// - /// Returns an async that waits until the tween is killed or started - /// (meaning when the tween is set in a playing state the first time, after any eventual delay). - /// It can be used inside an async operation. - /// Example usage:await myTween.AsyncWaitForPosition(); - /// - /// Position (loops included, delays excluded) to wait for - public static async System.Threading.Tasks.Task AsyncWaitForPosition(this Tween t, float position) - { - if (!t.active) { - if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t); - return; - } - while (t.active && t.position * (t.CompletedLoops() + 1) < position) await System.Threading.Tasks.Task.Yield(); - } - - /// - /// Returns an async that waits until the tween is killed. - /// It can be used inside an async operation. - /// Example usage:await myTween.AsyncWaitForKill(); - /// - public static async System.Threading.Tasks.Task AsyncWaitForStart(this Tween t) - { - if (!t.active) { - if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t); - return; - } - while (t.active && !t.playedOnce) await System.Threading.Tasks.Task.Yield(); - } - - #endregion -#endif - - #endregion - - #endregion -#endif - } - - // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ - // ███ CLASSES █████████████████████████████████████████████████████████████████████████████████████████████████████████ - // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ - -#if UNITY_5_3_OR_NEWER || UNITY_2017_1_OR_NEWER - public static class DOTweenCYInstruction - { - public class WaitForCompletion : CustomYieldInstruction - { - public override bool keepWaiting { get { - return t.active && !t.IsComplete(); - }} - readonly Tween t; - public WaitForCompletion(Tween tween) - { - t = tween; - } - } - - public class WaitForRewind : CustomYieldInstruction - { - public override bool keepWaiting { get { - return t.active && (!t.playedOnce || t.position * (t.CompletedLoops() + 1) > 0); - }} - readonly Tween t; - public WaitForRewind(Tween tween) - { - t = tween; - } - } - - public class WaitForKill : CustomYieldInstruction - { - public override bool keepWaiting { get { - return t.active; - }} - readonly Tween t; - public WaitForKill(Tween tween) - { - t = tween; - } - } - - public class WaitForElapsedLoops : CustomYieldInstruction - { - public override bool keepWaiting { get { - return t.active && t.CompletedLoops() < elapsedLoops; - }} - readonly Tween t; - readonly int elapsedLoops; - public WaitForElapsedLoops(Tween tween, int elapsedLoops) - { - t = tween; - this.elapsedLoops = elapsedLoops; - } - } - - public class WaitForPosition : CustomYieldInstruction - { - public override bool keepWaiting { get { - return t.active && t.position * (t.CompletedLoops() + 1) < position; - }} - readonly Tween t; - readonly float position; - public WaitForPosition(Tween tween, float position) - { - t = tween; - this.position = position; - } - } - - public class WaitForStart : CustomYieldInstruction - { - public override bool keepWaiting { get { - return t.active && !t.playedOnce; - }} - readonly Tween t; - public WaitForStart(Tween tween) - { - t = tween; - } - } - } -#endif -} diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUnityVersion.cs.meta b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUnityVersion.cs.meta deleted file mode 100644 index 290189f..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUnityVersion.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 63c02322328255542995bd02b47b0457 -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUtils.cs b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUtils.cs deleted file mode 100644 index 12a365d..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUtils.cs +++ /dev/null @@ -1,167 +0,0 @@ -// Author: Daniele Giardini - http://www.demigiant.com -// Created: 2018/07/13 - -using System; -using System.Reflection; -using UnityEngine; -using DG.Tweening.Core; -using DG.Tweening.Plugins.Core.PathCore; -using DG.Tweening.Plugins.Options; - -#pragma warning disable 1591 -namespace DG.Tweening -{ - /// - /// Utility functions that deal with available Modules. - /// Modules defines: - /// - DOTAUDIO - /// - DOTPHYSICS - /// - DOTPHYSICS2D - /// - DOTSPRITE - /// - DOTUI - /// Extra defines set and used for implementation of external assets: - /// - DOTWEEN_TMP ► TextMesh Pro - /// - DOTWEEN_TK2D ► 2D Toolkit - /// - public static class DOTweenModuleUtils - { - static bool _initialized; - - #region Reflection - - /// - /// Called via Reflection by DOTweenComponent on Awake - /// -#if UNITY_2018_1_OR_NEWER - [UnityEngine.Scripting.Preserve] -#endif - public static void Init() - { - if (_initialized) return; - - _initialized = true; - DOTweenExternalCommand.SetOrientationOnPath += Physics.SetOrientationOnPath; - -#if UNITY_EDITOR -#if UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_5 || UNITY_2017_1 - UnityEditor.EditorApplication.playmodeStateChanged += PlaymodeStateChanged; -#else - UnityEditor.EditorApplication.playModeStateChanged += PlaymodeStateChanged; -#endif -#endif - } - -#if UNITY_2018_1_OR_NEWER -#pragma warning disable - [UnityEngine.Scripting.Preserve] - // Just used to preserve methods when building, never called - static void Preserver() - { - Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); - MethodInfo mi = typeof(MonoBehaviour).GetMethod("Stub"); - } -#pragma warning restore -#endif - - #endregion - -#if UNITY_EDITOR - // Fires OnApplicationPause in DOTweenComponent even when Editor is paused (otherwise it's only fired at runtime) -#if UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_5 || UNITY_2017_1 - static void PlaymodeStateChanged() - #else - static void PlaymodeStateChanged(UnityEditor.PlayModeStateChange state) -#endif - { - if (DOTween.instance == null) return; - DOTween.instance.OnApplicationPause(UnityEditor.EditorApplication.isPaused); - } -#endif - - // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ - // ███ INTERNAL CLASSES ████████████████████████████████████████████████████████████████████████████████████████████████ - // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████ - - public static class Physics - { - // Called via DOTweenExternalCommand callback - public static void SetOrientationOnPath(PathOptions options, Tween t, Quaternion newRot, Transform trans) - { -#if true // PHYSICS_MARKER - if (options.isRigidbody) ((Rigidbody)t.target).rotation = newRot; - else trans.rotation = newRot; -#else - trans.rotation = newRot; -#endif - } - - // Returns FALSE if the DOTween's Physics2D Module is disabled, or if there's no Rigidbody2D attached - public static bool HasRigidbody2D(Component target) - { -#if true // PHYSICS2D_MARKER - return target.GetComponent() != null; -#else - return false; -#endif - } - - #region Called via Reflection - - - // Called via Reflection by DOTweenPathInspector - // Returns FALSE if the DOTween's Physics Module is disabled, or if there's no rigidbody attached -#if UNITY_2018_1_OR_NEWER - [UnityEngine.Scripting.Preserve] -#endif - public static bool HasRigidbody(Component target) - { -#if true // PHYSICS_MARKER - return target.GetComponent() != null; -#else - return false; -#endif - } - - // Called via Reflection by DOTweenPath -#if UNITY_2018_1_OR_NEWER - [UnityEngine.Scripting.Preserve] -#endif - public static TweenerCore CreateDOTweenPathTween( - MonoBehaviour target, bool tweenRigidbody, bool isLocal, Path path, float duration, PathMode pathMode - ){ - TweenerCore t = null; - bool rBodyFoundAndTweened = false; -#if true // PHYSICS_MARKER - if (tweenRigidbody) { - Rigidbody rBody = target.GetComponent(); - if (rBody != null) { - rBodyFoundAndTweened = true; - t = isLocal - ? rBody.DOLocalPath(path, duration, pathMode) - : rBody.DOPath(path, duration, pathMode); - } - } -#endif -#if true // PHYSICS2D_MARKER - if (!rBodyFoundAndTweened && tweenRigidbody) { - Rigidbody2D rBody2D = target.GetComponent(); - if (rBody2D != null) { - rBodyFoundAndTweened = true; - t = isLocal - ? rBody2D.DOLocalPath(path, duration, pathMode) - : rBody2D.DOPath(path, duration, pathMode); - } - } -#endif - if (!rBodyFoundAndTweened) { - t = isLocal - ? target.transform.DOLocalPath(path, duration, pathMode) - : target.transform.DOPath(path, duration, pathMode); - } - return t; - } - - #endregion - } - } -} diff --git a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUtils.cs.meta b/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUtils.cs.meta deleted file mode 100644 index ab62186..0000000 --- a/unity/Assets/Demigiant/DOTween/Modules/DOTweenModuleUtils.cs.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7bcaf917d9cf5b84090421a5a2abe42e -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: diff --git a/unity/Assets/Demigiant/DOTween/readme.txt b/unity/Assets/Demigiant/DOTween/readme.txt deleted file mode 100644 index 37ff7ef..0000000 --- a/unity/Assets/Demigiant/DOTween/readme.txt +++ /dev/null @@ -1,29 +0,0 @@ -DOTween and DOTween Pro are copyright (c) 2014-2018 Daniele Giardini - Demigiant - -// IMPORTANT!!! ///////////////////////////////////////////// -// Upgrading DOTween from versions older than 1.2.000 /////// -// (or DOTween Pro older than 1.0.000) ////////////////////// -------------------------------------------------------------- -If you're upgrading your project from a version of DOTween older than 1.2.000 (or DOTween Pro older than 1.0.000) please follow these instructions carefully. -1) Import the new version in the same folder as the previous one, overwriting old files. A lot of errors will appear but don't worry -2) Close and reopen Unity (and your project). This is fundamental: skipping this step will cause a bloodbath -3) Open DOTween's Utility Panel (Tools > Demigiant > DOTween Utility Panel) if it doesn't open automatically, then press "Setup DOTween...": this will run the upgrade setup -4) From the Add/Remove Modules panel that opens, activate/deactivate Modules for Unity systems and for external assets (Pro version only) - -// GET STARTED ////////////////////////////////////////////// - -- After importing a new DOTween update, select DOTween's Utility Panel from the "Tools/Demigiant" menu (if it doesn't open automatically) and press the "Setup DOTween..." button to activate/deactivate Modules. You can also access a Preferences Tab from there to choose default settings for DOTween. -- In your code, add "using DG.Tweening" to each class where you want to use DOTween. -- You're ready to tween. Check out the links below for full documentation and license info. - - -// LINKS /////////////////////////////////////////////////////// - -DOTween website (documentation, examples, etc): http://dotween.demigiant.com -DOTween license: http://dotween.demigiant.com/license.php -DOTween repository (Google Code): https://code.google.com/p/dotween/ -Demigiant website (documentation, examples, etc): http://www.demigiant.com - -// NOTES ////////////////////////////////////////////////////// - -- DOTween's Utility Panel can be found under "Tools > Demigiant > DOTween Utility Panel" and also contains other useful options, plus a tab to set DOTween's preferences \ No newline at end of file diff --git a/unity/Assets/Demigiant/DOTween/readme.txt.meta b/unity/Assets/Demigiant/DOTween/readme.txt.meta deleted file mode 100644 index 3799165..0000000 --- a/unity/Assets/Demigiant/DOTween/readme.txt.meta +++ /dev/null @@ -1,4 +0,0 @@ -fileFormatVersion: 2 -guid: fccfc62abf2eb0a4db614853430894fd -TextScriptImporter: - userData: diff --git a/unity/Assets/_brain_visualizer/script/Controller/BaseCanvasView.cs b/unity/Assets/_brain_visualizer/script/Controller/BaseCanvasView.cs index 7c53f20..c67ce79 100644 --- a/unity/Assets/_brain_visualizer/script/Controller/BaseCanvasView.cs +++ b/unity/Assets/_brain_visualizer/script/Controller/BaseCanvasView.cs @@ -3,7 +3,7 @@ using UnityEngine; using System; using UnityEngine.UI; -using DG.Tweening; +// using DG.Tweening; namespace dirox.emotiv.controller { @@ -59,28 +59,30 @@ public virtual void Deactivate() protected virtual void AnimateActivate (Action onComplete = null) { - if (canvasGroup.alpha < 0.1f) { - canvasGroup.DOFade (1, FADE_IN_TIME).OnComplete (() => { - makeItInteractable (true); - if (onComplete != null) - onComplete.Invoke (); - }); - } else { - canvasGroup.alpha = 1; - makeItInteractable (true); - if (onComplete != null) - onComplete.Invoke (); - } + // Tempory comment out for unity android build + // if (canvasGroup.alpha < 0.1f) { + // canvasGroup.DOFade (1, FADE_IN_TIME).OnComplete (() => { + // makeItInteractable (true); + // if (onComplete != null) + // onComplete.Invoke (); + // }); + // } else { + // canvasGroup.alpha = 1; + // makeItInteractable (true); + // if (onComplete != null) + // onComplete.Invoke (); + // } isActive = true; } protected virtual void AnimateActivateOnly () { - if (canvasGroup.alpha < 0.1f) { - canvasGroup.DOFade (1, FADE_IN_TIME); - } else { - canvasGroup.alpha = 1; - } + // Tempory comment out for unity android build + // if (canvasGroup.alpha < 0.1f) { + // canvasGroup.DOFade (1, FADE_IN_TIME); + // } else { + // canvasGroup.alpha = 1; + // } } protected void makeItInteractable () @@ -95,19 +97,20 @@ protected void makeItInteractable (bool enabled) } protected virtual void AnimateDeactivate (Action onComplete = null) - { - if (canvasGroup.alpha > 0.9f) - canvasGroup.DOFade (0, FADE_OUT_TIME).OnComplete(()=> { - makeItInteractable(false); - if (onComplete != null) - onComplete.Invoke(); - }); - else { - canvasGroup.alpha = 0; - makeItInteractable(false); - if (onComplete != null) - onComplete.Invoke(); - } + { + // Tempory comment out for unity android build + // if (canvasGroup.alpha > 0.9f) + // canvasGroup.DOFade (0, FADE_OUT_TIME).OnComplete(()=> { + // makeItInteractable(false); + // if (onComplete != null) + // onComplete.Invoke(); + // }); + // else { + // canvasGroup.alpha = 0; + // makeItInteractable(false); + // if (onComplete != null) + // onComplete.Invoke(); + // } isActive = false; } } diff --git a/unity/Assets/_brain_visualizer/script/Controller/ConnectHeadset/ConnectHeadsetController.cs b/unity/Assets/_brain_visualizer/script/Controller/ConnectHeadset/ConnectHeadsetController.cs index 5ef13f5..973ffcc 100644 --- a/unity/Assets/_brain_visualizer/script/Controller/ConnectHeadset/ConnectHeadsetController.cs +++ b/unity/Assets/_brain_visualizer/script/Controller/ConnectHeadset/ConnectHeadsetController.cs @@ -3,7 +3,7 @@ using UnityEngine.UI; using Zenject; using System; -using DG.Tweening; +// using DG.Tweening; using EmotivUnityPlugin; @@ -160,7 +160,8 @@ IEnumerator ChangeCanvasScaleMode(float delayTime, bool isHeadsetListForm) rootCanvasScaler.matchWidthOrHeight = 0.5f; tempColor.a = 0f; yield return new WaitForSeconds(delayTime); - fadeImage.DOColor(tempColor, delayTime); + // Tempory comment out for unity android build + // fadeImage.DOColor(tempColor, delayTime); } bool updateCortexStates () diff --git a/unity/ProjectSettings/ProjectSettings.asset b/unity/ProjectSettings/ProjectSettings.asset index 0880b52..e1f93fc 100644 --- a/unity/ProjectSettings/ProjectSettings.asset +++ b/unity/ProjectSettings/ProjectSettings.asset @@ -265,8 +265,8 @@ PlayerSettings: AndroidTargetDevices: 0 AndroidSplashScreenScale: 0 androidSplashScreen: {fileID: 0} - AndroidKeystoreName: D:/Saved/unity_android4.keystore - AndroidKeyaliasName: android_key + AndroidKeystoreName: + AndroidKeyaliasName: AndroidEnableArmv9SecurityFeatures: 0 AndroidEnableArm64MTE: 0 AndroidBuildApkPerCpuArchitecture: 0 diff --git a/unity/ProjectSettings/UnityConnectSettings.asset b/unity/ProjectSettings/UnityConnectSettings.asset index c3ae9a0..2d81664 100644 --- a/unity/ProjectSettings/UnityConnectSettings.asset +++ b/unity/ProjectSettings/UnityConnectSettings.asset @@ -9,6 +9,7 @@ UnityConnectSettings: m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events m_EventUrl: https://cdp.cloud.unity3d.com/v1/events m_ConfigUrl: https://config.uca.cloud.unity3d.com + m_DashboardUrl: https://dashboard.unity3d.com m_TestInitMode: 0 CrashReportingSettings: m_EventUrl: https://perf-events.cloud.unity3d.com @@ -22,6 +23,7 @@ UnityConnectSettings: m_Enabled: 0 m_TestMode: 0 m_InitializeOnStartup: 1 + m_PackageRequiringCoreStatsPresent: 1 UnityAdsSettings: m_Enabled: 0 m_InitializeOnStartup: 1 From 47320c24e5d700794af15927a4efcbf73bd277e9 Mon Sep 17 00:00:00 2001 From: tung_tung Date: Thu, 5 Dec 2024 01:00:46 +0700 Subject: [PATCH 06/24] update for bci interface for game --- unity/Assets/Plugins/Emotiv-Unity-Plugin | 2 +- unity/Assets/SimpleExample.cs | 115 ++++++++++++++--------- 2 files changed, 72 insertions(+), 45 deletions(-) diff --git a/unity/Assets/Plugins/Emotiv-Unity-Plugin b/unity/Assets/Plugins/Emotiv-Unity-Plugin index 885f2f8..ba294f4 160000 --- a/unity/Assets/Plugins/Emotiv-Unity-Plugin +++ b/unity/Assets/Plugins/Emotiv-Unity-Plugin @@ -1 +1 @@ -Subproject commit 885f2f871c5e8ff7fd4e2ca857713463e76aa11c +Subproject commit ba294f449bd7e89d65c8b038c63ea164bc49a6a9 diff --git a/unity/Assets/SimpleExample.cs b/unity/Assets/SimpleExample.cs index 25b232a..9c9015b 100644 --- a/unity/Assets/SimpleExample.cs +++ b/unity/Assets/SimpleExample.cs @@ -16,10 +16,9 @@ public class SimpleExample : MonoBehaviour private bool _isStarted = false; EmotivUnityItf _eItf = EmotivUnityItf.Instance; + BCIGameItf _bciGameItf = BCIGameItf.Instance; float _timerDataUpdate = 0; const float TIME_UPDATE_DATA = 1f; - bool _isDataBufferUsing = false; // default subscribed data will not saved to Data buffer - [SerializeField] public InputField HeadsetId; // headsetId [SerializeField] public InputField RecordTitle; // record Title @@ -47,13 +46,13 @@ public class SimpleExample : MonoBehaviour private const string FineLocationPermission = "android.permission.ACCESS_FINE_LOCATION"; private const string BluetoothScanPermission = "android.permission.BLUETOOTH_SCAN"; private const string BluetoothConnectPermission = "android.permission.BLUETOOTH_CONNECT"; - private const string WriteExternalStoragePermission = "android.permission.WRITE_EXTERNAL_STORAGE"; + // private const string WriteExternalStoragePermission = "android.permission.WRITE_EXTERNAL_STORAGE"; private readonly string[] permissions = { FineLocationPermission, BluetoothScanPermission, - BluetoothConnectPermission, - WriteExternalStoragePermission + BluetoothConnectPermission + // WriteExternalStoragePermission }; private bool HasAllPermissions() @@ -87,17 +86,18 @@ IEnumerator RequestPermissions() { RequestPermission(BluetoothConnectPermission); } - if (!HasPermission(WriteExternalStoragePermission)) - { - RequestPermission(WriteExternalStoragePermission); - } + // if (!HasPermission(WriteExternalStoragePermission)) + // { + // RequestPermission(WriteExternalStoragePermission); + // } } // start EmotivUnityItf for android private void StartEmotivUnityItfForAndroid() { if (HasAllPermissions()) { AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); - _eItf.Start(unityPlayer.GetStatic("currentActivity")); + AndroidJavaObject currentActivity = unityPlayer.GetStatic("currentActivity"); + _bciGameItf.Start(AppConfig.ClientId, AppConfig.ClientSecret, AppConfig.UserName, AppConfig.Password, currentActivity); _isStarted = true; } else if (!HasAllPermissions()) { @@ -129,15 +129,13 @@ void Start() if (_isStarted) return; - // init EmotivUnityItf without data buffer using - _eItf.Init(AppConfig.ClientId, AppConfig.ClientSecret, _appName, _appVersion, AppConfig.UserName, AppConfig.Password, _isDataBufferUsing); - #if UNITY_ANDROID StartEmotivUnityItfForAndroid(); # elif UNITY_IOS UnityEngine.Debug.Log("SimpleExp: Start EmotivUnityItf for ios"); #else UnityEngine.Debug.Log("SimpleExp: Start EmotivUnityItf for desktop"); + _eItf.Init(AppConfig.ClientId, AppConfig.ClientSecret, _appName, _appVersion, AppConfig.UserName, AppConfig.Password); _eItf.Start(); _isStarted = true; #endif @@ -151,7 +149,7 @@ void Update() return; _timerDataUpdate -= TIME_UPDATE_DATA; - if ( _eItf.MessageLog.Contains("Get Error:")) { + if ( _bciGameItf.GetLogMessage().Contains("Get Error:")) { // show error in red color MessageLog.color = Color.red; } @@ -159,7 +157,11 @@ void Update() // update message log MessageLog.color = Color.black; } - MessageLog.text = _eItf.MessageLog; + MessageLog.text = _bciGameItf.GetLogMessage(); + + // get detected headset lists + // List detectedHeadsets = _bciGameItf.GetDetectedHeadsets(); + #if UNITY_ANDROID // check all permissions are granted @@ -168,11 +170,11 @@ void Update() } #endif - if (!_eItf.IsAuthorizedOK) + if (!_bciGameItf.IsAuthorized()) return; // Check to call scan headset if no session is created and no scanning headset - if (!_eItf.IsSessionCreated && !DataStreamManager.Instance.IsHeadsetScanning) { + if (!_bciGameItf.IsSessionCreated() && !_bciGameItf.IsHeadsetScanning()) { // TODO :Start scanning headset at headset list screen // DataStreamManager.Instance.ScanHeadsets(); } @@ -182,24 +184,40 @@ void Update() // If save data to Data buffer. You can do the same EEG to get other data streams // Otherwise check output data at OnEEGDataReceived(), OnMotionDataReceived() ..etc.. - if (_isDataBufferUsing) { - // get eeg data - if (_eItf.GetNumberEEGSamples() > 0) { - string eegHeaderStr = "EEG Header: "; - string eegDataStr = "EEG Data: "; - foreach (var ele in _eItf.GetEEGChannels()) { - string chanStr = ChannelStringList.ChannelToString(ele); - double[] data = _eItf.GetEEGData(ele); - eegHeaderStr += chanStr + ", "; - if (data != null && data.Length > 0) - eegDataStr += data[0].ToString() + ", "; - else - eegDataStr += "null, "; // for null value - } - string msgLog = eegHeaderStr + "\n" + eegDataStr; - MessageLog.text = msgLog; - } - } + // get contact quality and battery level of the headset + if (_bciGameItf.GetNumberCQSamples() > 0) { + BatteryInfo batteryInfo = _bciGameItf.GetBattery(); + UnityEngine.Debug.Log("Battery: " + batteryInfo.overallBattery + ", batteryleft: " + batteryInfo.batteryLeft + ", batteryRight: " + batteryInfo.batteryRight); + + // get contact quality for channel t7 and t8 + double cqT7 = _bciGameItf.GetContactQuality(Channel_t.CHAN_T7); + double cqT8 = _bciGameItf.GetContactQuality(Channel_t.CHAN_T8); + UnityEngine.Debug.Log("CQ T7: " + cqT7 + ", CQ T8: " + cqT8); + } + + // get training done + if (_bciGameItf.IsTrainingCompleted()) { + UnityEngine.Debug.Log("Training done" + _bciGameItf.GetMentalCommandActionPower() + " is good mcAction " + _bciGameItf.IsGoodMCAction()); + } + + // if (_isDataBufferUsing) { + // // get eeg data + // if (_eItf.GetNumberEEGSamples() > 0) { + // string eegHeaderStr = "EEG Header: "; + // string eegDataStr = "EEG Data: "; + // foreach (var ele in _eItf.GetEEGChannels()) { + // string chanStr = ChannelStringList.ChannelToString(ele); + // double[] data = _eItf.GetEEGData(ele); + // eegHeaderStr += chanStr + ", "; + // if (data != null && data.Length > 0) + // eegDataStr += data[0].ToString() + ", "; + // else + // eegDataStr += "null, "; // for null value + // } + // string msgLog = eegHeaderStr + "\n" + eegDataStr; + // MessageLog.text = msgLog; + // } + // } } @@ -208,7 +226,7 @@ void Update() /// public void onQueryHeadsetBtnClick() { Debug.Log("onQueryHeadsetBtnClick"); - _eItf.QueryHeadsets(); + _bciGameItf.QueryHeadsets(); } @@ -217,9 +235,9 @@ public void onQueryHeadsetBtnClick() { /// public void onCreateSessionBtnClick() { Debug.Log("onCreateSessionBtnClick"); - if (!_eItf.IsSessionCreated) + if (!_bciGameItf.IsSessionCreated()) { - _eItf.CreateSessionWithHeadset(HeadsetId.text); + _bciGameItf.StartStreamData(HeadsetId.text); } else { @@ -310,7 +328,7 @@ public void onUnsubscribeBtnClick() { /// public void onLoadProfileBtnClick() { Debug.Log("onLoadProfileBtnClick " + ProfileName.text); - _eItf.LoadProfile(ProfileName.text); + _bciGameItf.CreatePlayer(ProfileName.text); } /// @@ -318,7 +336,7 @@ public void onLoadProfileBtnClick() { /// public void onUnLoadProfileBtnClick() { Debug.Log("onUnLoadProfileBtnClick " + ProfileName.text); - _eItf.UnLoadProfile(ProfileName.text); + _eItf.UnLoadProfile(); } /// @@ -333,10 +351,19 @@ public void onSaveProfileBtnClick() { /// start a mental command training action /// public void onStartMCTrainingBtnClick() { - if (_eItf.IsProfileLoaded) - _eItf.StartMCTraining(ActionNameList.captionText.text); - else - UnityEngine.Debug.LogError("onStartMCTrainingBtnClick: Please load a profile before starting training."); + + if (ActionNameList.captionText.text == "neutral") { + _bciGameItf.StartNeutralTraining(); + } + else { + _bciGameItf.StartTraining(); + } + + + // if (_eItf.IsProfileLoaded) + // _eItf.StartMCTraining(ActionNameList.captionText.text); + // else + // UnityEngine.Debug.LogError("onStartMCTrainingBtnClick: Please load a profile before starting training."); } /// From 2be6894e8530955f8c3a798b2964443406a5dd17 Mon Sep 17 00:00:00 2001 From: tung_tung Date: Fri, 6 Dec 2024 17:55:20 +0700 Subject: [PATCH 07/24] update unity-plugin commit --- unity/Assets/Plugins/Emotiv-Unity-Plugin | 2 +- unity/Assets/SimpleExample.cs | 6 ------ .../Controller/ConnectHeadset/ConnectHeadsetController.cs | 4 ---- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/unity/Assets/Plugins/Emotiv-Unity-Plugin b/unity/Assets/Plugins/Emotiv-Unity-Plugin index ba294f4..a799944 160000 --- a/unity/Assets/Plugins/Emotiv-Unity-Plugin +++ b/unity/Assets/Plugins/Emotiv-Unity-Plugin @@ -1 +1 @@ -Subproject commit ba294f449bd7e89d65c8b038c63ea164bc49a6a9 +Subproject commit a799944275cb3d70341ae03e79158e16f249d5fd diff --git a/unity/Assets/SimpleExample.cs b/unity/Assets/SimpleExample.cs index 9c9015b..91ed16b 100644 --- a/unity/Assets/SimpleExample.cs +++ b/unity/Assets/SimpleExample.cs @@ -172,12 +172,6 @@ void Update() if (!_bciGameItf.IsAuthorized()) return; - - // Check to call scan headset if no session is created and no scanning headset - if (!_bciGameItf.IsSessionCreated() && !_bciGameItf.IsHeadsetScanning()) { - // TODO :Start scanning headset at headset list screen - // DataStreamManager.Instance.ScanHeadsets(); - } // Check buttons interactable CheckButtonsInteractable(); diff --git a/unity/Assets/_brain_visualizer/script/Controller/ConnectHeadset/ConnectHeadsetController.cs b/unity/Assets/_brain_visualizer/script/Controller/ConnectHeadset/ConnectHeadsetController.cs index 973ffcc..0e85263 100644 --- a/unity/Assets/_brain_visualizer/script/Controller/ConnectHeadset/ConnectHeadsetController.cs +++ b/unity/Assets/_brain_visualizer/script/Controller/ConnectHeadset/ConnectHeadsetController.cs @@ -141,10 +141,6 @@ public override void Activate() void Update() { - if (IsActive && !DataStreamManager.Instance.IsHeadsetScanning) { - // Start scanning headset at headset list screen - DataStreamManager.Instance.ScanHeadsets(); - } } IEnumerator ChangeCanvasScaleMode(float delayTime, bool isHeadsetListForm) From c37311b19c87b88930fbc17b8b12a8d40565d971 Mon Sep 17 00:00:00 2001 From: tung_tung Date: Wed, 18 Dec 2024 18:41:17 +0700 Subject: [PATCH 08/24] update training api --- .../Plugins/Android/AndroidManifest.xml | 6 +- unity/Assets/Plugins/Emotiv-Unity-Plugin | 2 +- unity/Assets/SimpleExample.cs | 113 ++++++++++++------ 3 files changed, 84 insertions(+), 37 deletions(-) diff --git a/unity/Assets/Plugins/Android/AndroidManifest.xml b/unity/Assets/Plugins/Android/AndroidManifest.xml index b8174c1..f2592aa 100644 --- a/unity/Assets/Plugins/Android/AndroidManifest.xml +++ b/unity/Assets/Plugins/Android/AndroidManifest.xml @@ -5,8 +5,10 @@ package="com.emotiv.unityexample"> - - + + diff --git a/unity/Assets/Plugins/Emotiv-Unity-Plugin b/unity/Assets/Plugins/Emotiv-Unity-Plugin index a799944..c00e4dc 160000 --- a/unity/Assets/Plugins/Emotiv-Unity-Plugin +++ b/unity/Assets/Plugins/Emotiv-Unity-Plugin @@ -1 +1 @@ -Subproject commit a799944275cb3d70341ae03e79158e16f249d5fd +Subproject commit c00e4dcd7145412b1ef2da0a73762a2530b754a5 diff --git a/unity/Assets/SimpleExample.cs b/unity/Assets/SimpleExample.cs index 91ed16b..60c468c 100644 --- a/unity/Assets/SimpleExample.cs +++ b/unity/Assets/SimpleExample.cs @@ -15,6 +15,8 @@ public class SimpleExample : MonoBehaviour private string _appVersion = "3.3.0"; private bool _isStarted = false; + Logger _logger = Logger.Instance; + EmotivUnityItf _eItf = EmotivUnityItf.Instance; BCIGameItf _bciGameItf = BCIGameItf.Instance; float _timerDataUpdate = 0; @@ -46,20 +48,33 @@ public class SimpleExample : MonoBehaviour private const string FineLocationPermission = "android.permission.ACCESS_FINE_LOCATION"; private const string BluetoothScanPermission = "android.permission.BLUETOOTH_SCAN"; private const string BluetoothConnectPermission = "android.permission.BLUETOOTH_CONNECT"; - // private const string WriteExternalStoragePermission = "android.permission.WRITE_EXTERNAL_STORAGE"; + private const string BluetoothPermission = "android.permission.BLUETOOTH"; - private readonly string[] permissions = { - FineLocationPermission, - BluetoothScanPermission, - BluetoothConnectPermission - // WriteExternalStoragePermission - }; private bool HasAllPermissions() { - foreach (string permission in permissions) + // check location permission + if (!HasPermission(FineLocationPermission)) { - if (!Permission.HasUserAuthorizedPermission(permission)) + return false; + } + + // check bluetooth permission + AndroidJavaClass jc = new AndroidJavaClass("android.os.Build$VERSION"); + int androidVersion = jc.GetStatic("SDK_INT"); + + if (androidVersion >= 31) + { + // Android 12 or higher. need bluetooth scan and connect permission + if (!HasPermission(BluetoothScanPermission) || !HasPermission(BluetoothConnectPermission)) + { + return false; + } + } + else + { + // Android 11 or lower. need bluetooth permission + if (!HasPermission(BluetoothPermission)) { return false; } @@ -67,29 +82,30 @@ private bool HasAllPermissions() return true; } - - IEnumerator RequestPermissions() + private IEnumerator RequestPermissions() { - yield return new WaitForSeconds(1f); + // check android version . if android version >= 31, need bluetooth scan and connect permission otherwise need bluetooth permission only. the location permission is always needed + AndroidJavaClass jc = new AndroidJavaClass("android.os.Build$VERSION"); + int androidVersion = jc.GetStatic("SDK_INT"); + string[] _permissions; - if (!HasPermission(FineLocationPermission)) + if (androidVersion >= 30) { - RequestPermission(FineLocationPermission); + _permissions = new string[] { FineLocationPermission, BluetoothScanPermission, BluetoothConnectPermission }; } - - if (!HasPermission(BluetoothScanPermission)) + else { - RequestPermission(BluetoothScanPermission); + _permissions = new string[] { FineLocationPermission, BluetoothPermission }; } - if (!HasPermission(BluetoothConnectPermission)) + foreach (var permission in _permissions) { - RequestPermission(BluetoothConnectPermission); + if (!HasPermission(permission)) + { + RequestPermission(permission); + yield return new WaitUntil(() => HasPermission(permission)); + } } - // if (!HasPermission(WriteExternalStoragePermission)) - // { - // RequestPermission(WriteExternalStoragePermission); - // } } // start EmotivUnityItf for android @@ -100,7 +116,7 @@ private void StartEmotivUnityItfForAndroid() { _bciGameItf.Start(AppConfig.ClientId, AppConfig.ClientSecret, AppConfig.UserName, AppConfig.Password, currentActivity); _isStarted = true; } - else if (!HasAllPermissions()) { + else { StartCoroutine(RequestPermissions()); } } @@ -128,6 +144,8 @@ void Start() { if (_isStarted) return; + + _logger.Init(); #if UNITY_ANDROID StartEmotivUnityItfForAndroid(); @@ -159,6 +177,7 @@ void Update() } MessageLog.text = _bciGameItf.GetLogMessage(); + // get detected headset lists // List detectedHeadsets = _bciGameItf.GetDetectedHeadsets(); @@ -172,6 +191,10 @@ void Update() if (!_bciGameItf.IsAuthorized()) return; + + + // check connect headset state + // ConnectHeadsetStates connectHeadsetState = _bciGameItf.GetConnectHeadsetState(); // Check buttons interactable CheckButtonsInteractable(); @@ -189,6 +212,17 @@ void Update() UnityEngine.Debug.Log("CQ T7: " + cqT7 + ", CQ T8: " + cqT8); } + // if (_bciGameItf.GetNumberEQSamples() > 0) { + // BatteryInfo batteryInfo = _bciGameItf.GetBattery(); + // UnityEngine.Debug.Log("qqqq Battery: " + batteryInfo.overallBattery + ", batteryleft: " + batteryInfo.batteryLeft + ", batteryRight: " + batteryInfo.batteryRight); + + // // get contact quality for channel t7 and t8 + // double cqT7 = _bciGameItf.GetEQ(Channel_t.CHAN_T7); + // double cqT8 = _bciGameItf.GetEQ(Channel_t.CHAN_T8); + // UnityEngine.Debug.Log("qqqqqq CQ T7: " + cqT7 + ", CQ T8: " + cqT8); + // } + + // get training done if (_bciGameItf.IsTrainingCompleted()) { UnityEngine.Debug.Log("Training done" + _bciGameItf.GetMentalCommandActionPower() + " is good mcAction " + _bciGameItf.IsGoodMCAction()); @@ -347,10 +381,10 @@ public void onSaveProfileBtnClick() { public void onStartMCTrainingBtnClick() { if (ActionNameList.captionText.text == "neutral") { - _bciGameItf.StartNeutralTraining(); + _bciGameItf.StartNeutralTrainingAddtive(); } else { - _bciGameItf.StartTraining(); + _bciGameItf.StartTrainingAddative(); } @@ -374,21 +408,32 @@ public void onAcceptMCTrainingBtnClick() { /// reject a mental command training /// public void onRejectMCTrainingBtnClick() { - if (_eItf.IsProfileLoaded) - _eItf.RejectMCTraining(); - else - UnityEngine.Debug.LogError("onRejectMCTrainingBtnClick: Please load a profile before start training."); + + if (ActionNameList.captionText.text == "neutral") { + _bciGameItf.StartNeutralTraining(); + } + else { + _bciGameItf.StartTraining(); + } + + // if (_eItf.IsProfileLoaded) + // _eItf.RejectMCTraining(); + // else + // UnityEngine.Debug.LogError("onRejectMCTrainingBtnClick: Please load a profile before start training."); } /// /// erase a mental command training /// public void onEraseMCTrainingBtnClick() { + + _bciGameItf.EraseAllMCTraining(); + Debug.Log("onEraseMCTrainingBtnClick " + ActionNameList.captionText.text); - if (_eItf.IsProfileLoaded) - _eItf.EraseMCTraining(ActionNameList.captionText.text); - else - UnityEngine.Debug.LogError("onAcceptMCTrainingBtnClick: Please load a profile before start training."); + // if (_eItf.IsProfileLoaded) + // _eItf.EraseMCTraining(ActionNameList.captionText.text); + // else + // UnityEngine.Debug.LogError("onAcceptMCTrainingBtnClick: Please load a profile before start training."); } From 0d466eac94933645be04da4fef9d12d73e7b5df8 Mon Sep 17 00:00:00 2001 From: tung_tung Date: Thu, 19 Dec 2024 17:07:14 +0700 Subject: [PATCH 09/24] update to support sensitive and clear data --- unity/Assets/Plugins/Emotiv-Unity-Plugin | 2 +- unity/Assets/SimpleExample.cs | 50 ++++++------------------ 2 files changed, 13 insertions(+), 39 deletions(-) diff --git a/unity/Assets/Plugins/Emotiv-Unity-Plugin b/unity/Assets/Plugins/Emotiv-Unity-Plugin index c00e4dc..4992b20 160000 --- a/unity/Assets/Plugins/Emotiv-Unity-Plugin +++ b/unity/Assets/Plugins/Emotiv-Unity-Plugin @@ -1 +1 @@ -Subproject commit c00e4dcd7145412b1ef2da0a73762a2530b754a5 +Subproject commit 4992b20d7a2e20f9dabbe4d0f21a74f59a6f4a60 diff --git a/unity/Assets/SimpleExample.cs b/unity/Assets/SimpleExample.cs index 60c468c..4e010a6 100644 --- a/unity/Assets/SimpleExample.cs +++ b/unity/Assets/SimpleExample.cs @@ -226,7 +226,12 @@ void Update() // get training done if (_bciGameItf.IsTrainingCompleted()) { UnityEngine.Debug.Log("Training done" + _bciGameItf.GetMentalCommandActionPower() + " is good mcAction " + _bciGameItf.IsGoodMCAction()); - } + } + + // get sensitivity + // if (_bciGameItf.GetFirstMCActionSensitivity() > -1) { + // UnityEngine.Debug.Log("First MC Action Sensitivity: " + _bciGameItf.GetFirstMCActionSensitivity()); + // } // if (_isDataBufferUsing) { // // get eeg data @@ -378,48 +383,23 @@ public void onSaveProfileBtnClick() { /// /// start a mental command training action /// - public void onStartMCTrainingBtnClick() { - - if (ActionNameList.captionText.text == "neutral") { - _bciGameItf.StartNeutralTrainingAddtive(); - } - else { - _bciGameItf.StartTrainingAddative(); - } - + public void onStartMCTrainingBtnClick() { - // if (_eItf.IsProfileLoaded) - // _eItf.StartMCTraining(ActionNameList.captionText.text); - // else - // UnityEngine.Debug.LogError("onStartMCTrainingBtnClick: Please load a profile before starting training."); + _bciGameItf.StartTraining(ActionNameList.captionText.text); } /// /// accept a mental command training /// public void onAcceptMCTrainingBtnClick() { - if (_eItf.IsProfileLoaded) - _eItf.AcceptMCTraining(); - else - UnityEngine.Debug.LogError("onAcceptMCTrainingBtnClick: Please load a profile before start training."); + _bciGameItf.AcceptTraining(); } /// /// reject a mental command training /// public void onRejectMCTrainingBtnClick() { - - if (ActionNameList.captionText.text == "neutral") { - _bciGameItf.StartNeutralTraining(); - } - else { - _bciGameItf.StartTraining(); - } - - // if (_eItf.IsProfileLoaded) - // _eItf.RejectMCTraining(); - // else - // UnityEngine.Debug.LogError("onRejectMCTrainingBtnClick: Please load a profile before start training."); + _bciGameItf.RejectTraining(); } /// @@ -427,20 +407,14 @@ public void onRejectMCTrainingBtnClick() { /// public void onEraseMCTrainingBtnClick() { - _bciGameItf.EraseAllMCTraining(); - - Debug.Log("onEraseMCTrainingBtnClick " + ActionNameList.captionText.text); - // if (_eItf.IsProfileLoaded) - // _eItf.EraseMCTraining(ActionNameList.captionText.text); - // else - // UnityEngine.Debug.LogError("onAcceptMCTrainingBtnClick: Please load a profile before start training."); + _bciGameItf.EraseDataForMCTrainingAction(ActionNameList.captionText.text); } void OnApplicationQuit() { Debug.Log("Application ending after " + Time.time + " seconds"); - _eItf.Stop(); + _bciGameItf.Stop(); } private void CheckButtonsInteractable() From 7e088c0d5821930a7b95b63b1f6b09cfb31334ae Mon Sep 17 00:00:00 2001 From: tung_tung Date: Wed, 8 Jan 2025 16:26:58 +0700 Subject: [PATCH 10/24] support save token to file --- unity/Assets/Plugins/Emotiv-Unity-Plugin | 2 +- unity/Assets/SimpleExample.cs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/unity/Assets/Plugins/Emotiv-Unity-Plugin b/unity/Assets/Plugins/Emotiv-Unity-Plugin index 4992b20..274ddb4 160000 --- a/unity/Assets/Plugins/Emotiv-Unity-Plugin +++ b/unity/Assets/Plugins/Emotiv-Unity-Plugin @@ -1 +1 @@ -Subproject commit 4992b20d7a2e20f9dabbe4d0f21a74f59a6f4a60 +Subproject commit 274ddb4a663111ec1040316e8070021a28891694 diff --git a/unity/Assets/SimpleExample.cs b/unity/Assets/SimpleExample.cs index 4e010a6..aae24ca 100644 --- a/unity/Assets/SimpleExample.cs +++ b/unity/Assets/SimpleExample.cs @@ -145,6 +145,9 @@ void Start() if (_isStarted) return; + // init utils to create needed directory + Utils.Init(); + _logger.Init(); #if UNITY_ANDROID From d461bf4fe9a91e03dfbce43dc0a683ca3cfb6a6c Mon Sep 17 00:00:00 2001 From: tung_tung Date: Thu, 23 Jan 2025 18:02:30 +0700 Subject: [PATCH 11/24] COR-5540: support embedded lib for windows --- unity/Assets/Plugins/AppConfig.cs | 16 +- unity/Assets/Plugins/ConnectToCortex.cs | 6 +- unity/Assets/Plugins/Emotiv-Unity-Plugin | 2 +- unity/Assets/SimpleExample.cs | 360 ++++++++++------ unity/Assets/SimpleExample.unity | 454 +++++++++++++++++++- unity/Packages/manifest.json | 1 + unity/ProjectSettings/ProjectSettings.asset | 14 +- 7 files changed, 692 insertions(+), 161 deletions(-) diff --git a/unity/Assets/Plugins/AppConfig.cs b/unity/Assets/Plugins/AppConfig.cs index 2f2a997..e85ef61 100644 --- a/unity/Assets/Plugins/AppConfig.cs +++ b/unity/Assets/Plugins/AppConfig.cs @@ -3,13 +3,17 @@ /// public static class AppConfig { - public static string AppUrl = "wss://localhost:6868"; + public static string AppVersion = "1.1.0"; public static string AppName = "UnityApp"; + public static string ClientId = "put_your_client_id_here"; + public static string ClientSecret = "put_your_client_secret_here"; + public static bool IsDataBufferUsing = false; // Set false if you want to display data directly to MessageLog without storing in Data Buffer - // Please fill the clientId and client Secret of your application before starting. - public static string ClientId = ""; - public static string ClientSecret = ""; - public static string UserName = ""; + #if UNITY_ANDROID || UNITY_IOS + public static string UserName = ""; // for private login public static string Password = ""; - public static string AppVersion = "3.3.0"; + #elif !USE_EMBEDDED_LIB_WIN + public static string AppUrl = "wss://localhost:6868"; // for desktop without embedded cortex + #endif + } \ No newline at end of file diff --git a/unity/Assets/Plugins/ConnectToCortex.cs b/unity/Assets/Plugins/ConnectToCortex.cs index aee6d61..25aa8cf 100644 --- a/unity/Assets/Plugins/ConnectToCortex.cs +++ b/unity/Assets/Plugins/ConnectToCortex.cs @@ -16,12 +16,12 @@ void Start() { // set Application configuration _dataStream.SetAppConfig(AppConfig.ClientId, AppConfig.ClientSecret, - AppConfig.AppVersion, AppConfig.AppName, AppConfig.UserName, AppConfig.Password, - AppConfig.AppName, AppConfig.AppUrl, + AppConfig.AppVersion, AppConfig.AppName, "", "", + AppConfig.AppName, "", EmotivAppslicationPath()); // Init logger - #if !UNITY_ANDROID && !UNITY_IOS + #if !UNITY_ANDROID && !UNITY_IOS && !USE_EMBEDDED_LIB_WIN _logger.Init(); #endif diff --git a/unity/Assets/Plugins/Emotiv-Unity-Plugin b/unity/Assets/Plugins/Emotiv-Unity-Plugin index 274ddb4..e054b69 160000 --- a/unity/Assets/Plugins/Emotiv-Unity-Plugin +++ b/unity/Assets/Plugins/Emotiv-Unity-Plugin @@ -1 +1 @@ -Subproject commit 274ddb4a663111ec1040316e8070021a28891694 +Subproject commit e054b69f07e15d2d630ee74374c6b38f9861fd3c diff --git a/unity/Assets/SimpleExample.cs b/unity/Assets/SimpleExample.cs index aae24ca..d4888cb 100644 --- a/unity/Assets/SimpleExample.cs +++ b/unity/Assets/SimpleExample.cs @@ -4,21 +4,27 @@ using EmotivUnityPlugin; using UnityEngine.UI; using System; +using System.Threading.Tasks; #if UNITY_ANDROID using UnityEngine.Android; #endif + +#if USE_EMBEDDED_LIB_WIN +using Cdm.Authentication.Browser; +using Cdm.Authentication.OAuth2; +using System.Threading; +using System.Security.Cryptography; +using System.Text; +using Cdm.Authentication.Clients; +using Newtonsoft.Json; +#endif public class SimpleExample : MonoBehaviour { - // Please fill clientId and clientSecret of your application in AppConfig.cs before starting - private string _appName = "UnityApp"; - private string _appVersion = "3.3.0"; - private bool _isStarted = false; - + private bool _isEmotivUnityItfInitialized = false; // the flag to check if EmotivUnityItf is initialized and start connecting to Cortex or not Logger _logger = Logger.Instance; EmotivUnityItf _eItf = EmotivUnityItf.Instance; - BCIGameItf _bciGameItf = BCIGameItf.Instance; float _timerDataUpdate = 0; const float TIME_UPDATE_DATA = 1f; @@ -50,7 +56,6 @@ public class SimpleExample : MonoBehaviour private const string BluetoothConnectPermission = "android.permission.BLUETOOTH_CONNECT"; private const string BluetoothPermission = "android.permission.BLUETOOTH"; - private bool HasAllPermissions() { // check location permission @@ -113,8 +118,9 @@ private void StartEmotivUnityItfForAndroid() { if (HasAllPermissions()) { AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject currentActivity = unityPlayer.GetStatic("currentActivity"); - _bciGameItf.Start(AppConfig.ClientId, AppConfig.ClientSecret, AppConfig.UserName, AppConfig.Password, currentActivity); - _isStarted = true; + _eItf.Init(AppConfig.ClientId, AppConfig.ClientSecret, AppConfig.AppName, AppConfig.AppVersion, AppConfig.UserName, AppConfig.Password, _isDataBufferUsing); + _eItf.Start(currentActivity); + _isEmotivUnityItfInitialized = true; } else { StartCoroutine(RequestPermissions()); @@ -139,26 +145,137 @@ private static void RequestPermission(string permissionName) { } } #endif + + #if USE_EMBEDDED_LIB_WIN + private CrossPlatformBrowser _crossPlatformBrowser; + private AuthenticationSession _authenticationSession; + private CancellationTokenSource _cancellationTokenSource; + private static readonly char[] HEX_ARRAY = "0123456789abcdef".ToCharArray(); + + private string BytesToHex(byte[] bytes) + { + char[] hexChars = new char[bytes.Length * 2]; + for (int j = 0; j < bytes.Length; ++j) + { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = HEX_ARRAY[v >> 4]; + hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; + } + return new string(hexChars); + } + + private string Md5(string s) + { + try + { + using (var md5 = MD5.Create()) + { + byte[] inputBytes = Encoding.UTF8.GetBytes(s); + byte[] hashBytes = md5.ComputeHash(inputBytes); + return BytesToHex(hashBytes); + } + } + catch (Exception e) + { + Debug.LogError(e); + return string.Empty; + } + } + + private void InitForAuthentication() + { + _crossPlatformBrowser = new CrossPlatformBrowser(); + _crossPlatformBrowser.platformBrowsers.Add(RuntimePlatform.WindowsEditor, new WindowsSystemBrowser()); + _crossPlatformBrowser.platformBrowsers.Add(RuntimePlatform.WindowsPlayer, new WindowsSystemBrowser()); + + string server = "cerebrum.emotivcloud.com"; + string hash = Md5(AppConfig.ClientId); + string prefixRedirectUrl = "emotiv-" + hash; + string redirectUrl = prefixRedirectUrl + "://authorize"; + string serverUrl = $"https://{server}"; + + new RegistryConfig(prefixRedirectUrl).Configure(); + + var configuration = new AuthorizationCodeFlow.Configuration() + { + clientId = AppConfig.ClientId, + clientSecret = AppConfig.ClientSecret, + redirectUri = redirectUrl, + scope = "" + }; + var auth = new MockServerAuth(configuration, serverUrl); + _authenticationSession = new AuthenticationSession(auth, _crossPlatformBrowser); + _authenticationSession.loginTimeout = TimeSpan.FromSeconds(600); + } + + private async Task AuthenticateAsyncWin() + { + if (_authenticationSession != null) + { + // print log + _cancellationTokenSource?.Dispose(); + _cancellationTokenSource = new CancellationTokenSource(); + try + { + var accessTokenResponse = + await _authenticationSession.AuthenticateAsync(_cancellationTokenSource.Token); + + _eItf.LoginWithAuthenticationCode(accessTokenResponse.accessToken); + } + catch (AuthorizationCodeRequestException ex) + { + Debug.LogError($"{nameof(AuthorizationCodeRequestException)} " + + $"error: {ex.error.code}, description: {ex.error.description}, uri: {ex.error.uri}"); + } + catch (AccessTokenRequestException ex) + { + Debug.LogError($"{nameof(AccessTokenRequestException)} " + + $"error: {ex.error.code}, description: {ex.error.description}, uri: {ex.error.uri}"); + } + catch (Exception ex) + { + Debug.LogError( "Exception " + ex.Message); + } + } + } + + #endif + + protected void OnDestroy() + { + #if USE_EMBEDDED_LIB_WIN + _cancellationTokenSource?.Cancel(); + _authenticationSession?.Dispose(); + #endif + } void Start() { - if (_isStarted) + Utils.Init(); // init utils to create app directory and log directory + _logger.Init(); // init logger to save log to file to log directory + + #if USE_EMBEDDED_LIB_WIN + string[] args = Environment.GetCommandLineArgs(); + if (args.Length > 1) + { + MessageLog.text = "Process callback then quit."; + WindowsSystemBrowser.ProcessCallback(args[1]); return; - - // init utils to create needed directory - Utils.Init(); - - _logger.Init(); + } + else { + InitForAuthentication(); + } + #endif #if UNITY_ANDROID StartEmotivUnityItfForAndroid(); # elif UNITY_IOS - UnityEngine.Debug.Log("SimpleExp: Start EmotivUnityItf for ios"); + UnityEngine.Debug.Log("SimpleExp: Start EmotivUnityItf for ios. TODO"); #else UnityEngine.Debug.Log("SimpleExp: Start EmotivUnityItf for desktop"); - _eItf.Init(AppConfig.ClientId, AppConfig.ClientSecret, _appName, _appVersion, AppConfig.UserName, AppConfig.Password); + _eItf.Init(AppConfig.ClientId, AppConfig.ClientSecret, AppConfig.AppName, AppConfig.AppVersion, "", "", AppConfig.IsDataBufferUsing); _eItf.Start(); - _isStarted = true; + _isEmotivUnityItfInitialized = true; #endif } @@ -170,120 +287,84 @@ void Update() return; _timerDataUpdate -= TIME_UPDATE_DATA; - if ( _bciGameItf.GetLogMessage().Contains("Get Error:")) { - // show error in red color - MessageLog.color = Color.red; - } - else { - // update message log - MessageLog.color = Color.black; - } - MessageLog.text = _bciGameItf.GetLogMessage(); - - - // get detected headset lists - // List detectedHeadsets = _bciGameItf.GetDetectedHeadsets(); - - #if UNITY_ANDROID - // check all permissions are granted - if (!_isStarted) { + if (!_isEmotivUnityItfInitialized) { + // start EmotivUnityItf for android if not started StartEmotivUnityItfForAndroid(); } #endif - if (!_bciGameItf.IsAuthorized()) - return; - - - // check connect headset state - // ConnectHeadsetStates connectHeadsetState = _bciGameItf.GetConnectHeadsetState(); - // Check buttons interactable CheckButtonsInteractable(); + + // Display message log + MessageLog.text = _eItf.MessageLog; + + // Demo how to get detected headset lists + // List detectedHeadsets = _eItf.GetDetectedHeadsets(); + + // Demo how to get subcribed data if use Data Buffer + if (AppConfig.IsDataBufferUsing) { + // eeg data + // if (_eItf.GetNumberEEGSamples() > 0) { + // string eegHeaderStr = "EEG Header: "; + // string eegDataStr = "EEG Data: "; + // foreach (var ele in _eItf.GetEEGChannels()) { + // string chanStr = ChannelStringList.ChannelToString(ele); + // double[] data = _eItf.GetEEGData(ele); + // eegHeaderStr += chanStr + ", "; + // if (data != null && data.Length > 0) + // eegDataStr += data[0].ToString() + ", "; + // else + // eegDataStr += "null, "; // for null value + // } + // string msgLog = eegHeaderStr + "\n" + eegDataStr; + // MessageLog.text = msgLog; + // } + + // Demo how to get cq data + if (_eItf.GetNumberCQSamples() > 0) { + BatteryInfo batteryInfo = _eItf.GetBattery(); + // get contact quality for channel t7 and t8, similar for other channels + double cqT7 = _eItf.GetContactQuality(Channel_t.CHAN_T7); + double cqT8 = _eItf.GetContactQuality(Channel_t.CHAN_T8); + double cqOverall = _eItf.GetContactQuality(Channel_t.CHAN_CQ_OVERALL); + MessageLog.text = "CQ T7: " + cqT7 + ", CQ T8: " + cqT8 + " cq overall: " + cqOverall; + } + } - // If save data to Data buffer. You can do the same EEG to get other data streams - // Otherwise check output data at OnEEGDataReceived(), OnMotionDataReceived() ..etc.. - // get contact quality and battery level of the headset - if (_bciGameItf.GetNumberCQSamples() > 0) { - BatteryInfo batteryInfo = _bciGameItf.GetBattery(); - UnityEngine.Debug.Log("Battery: " + batteryInfo.overallBattery + ", batteryleft: " + batteryInfo.batteryLeft + ", batteryRight: " + batteryInfo.batteryRight); - - // get contact quality for channel t7 and t8 - double cqT7 = _bciGameItf.GetContactQuality(Channel_t.CHAN_T7); - double cqT8 = _bciGameItf.GetContactQuality(Channel_t.CHAN_T8); - UnityEngine.Debug.Log("CQ T7: " + cqT7 + ", CQ T8: " + cqT8); - } - - // if (_bciGameItf.GetNumberEQSamples() > 0) { - // BatteryInfo batteryInfo = _bciGameItf.GetBattery(); - // UnityEngine.Debug.Log("qqqq Battery: " + batteryInfo.overallBattery + ", batteryleft: " + batteryInfo.batteryLeft + ", batteryRight: " + batteryInfo.batteryRight); - - // // get contact quality for channel t7 and t8 - // double cqT7 = _bciGameItf.GetEQ(Channel_t.CHAN_T7); - // double cqT8 = _bciGameItf.GetEQ(Channel_t.CHAN_T8); - // UnityEngine.Debug.Log("qqqqqq CQ T7: " + cqT7 + ", CQ T8: " + cqT8); - // } - - - // get training done - if (_bciGameItf.IsTrainingCompleted()) { - UnityEngine.Debug.Log("Training done" + _bciGameItf.GetMentalCommandActionPower() + " is good mcAction " + _bciGameItf.IsGoodMCAction()); - } - - // get sensitivity - // if (_bciGameItf.GetFirstMCActionSensitivity() > -1) { - // UnityEngine.Debug.Log("First MC Action Sensitivity: " + _bciGameItf.GetFirstMCActionSensitivity()); - // } - - // if (_isDataBufferUsing) { - // // get eeg data - // if (_eItf.GetNumberEEGSamples() > 0) { - // string eegHeaderStr = "EEG Header: "; - // string eegDataStr = "EEG Data: "; - // foreach (var ele in _eItf.GetEEGChannels()) { - // string chanStr = ChannelStringList.ChannelToString(ele); - // double[] data = _eItf.GetEEGData(ele); - // eegHeaderStr += chanStr + ", "; - // if (data != null && data.Length > 0) - // eegDataStr += data[0].ToString() + ", "; - // else - // eegDataStr += "null, "; // for null value - // } - // string msgLog = eegHeaderStr + "\n" + eegDataStr; - // MessageLog.text = msgLog; - // } - // } + // Demo how to check Mentalcommand training completed and get data power + if (_eItf.IsMCTrainingCompleted) { + UnityEngine.Debug.Log("Training done. Action: " + _eItf.LatestMentalCommand.act + ", power: " + _eItf.LatestMentalCommand.pow); + } + } + // sign out button + public void onSignOutBtnClick() { + Debug.Log("onSignOutBtnClick"); + _eItf.Logout(); } - /// - /// create session - /// public void onQueryHeadsetBtnClick() { Debug.Log("onQueryHeadsetBtnClick"); - _bciGameItf.QueryHeadsets(); + _eItf.QueryHeadsets(); } + public async void onSignInBtnClick() { + Debug.Log("onSignInBtnClick"); + await AuthenticateAsyncWin(); + } - /// - /// create session - /// public void onCreateSessionBtnClick() { Debug.Log("onCreateSessionBtnClick"); - if (!_bciGameItf.IsSessionCreated()) - { - _bciGameItf.StartStreamData(HeadsetId.text); + if (!_eItf.IsSessionCreated) { + _eItf.CreateSessionWithHeadset(HeadsetId.text); } - else - { + else { UnityEngine.Debug.LogError("There is a session created."); } } - /// - /// start a record - /// public void onStartRecordBtnClick() { Debug.Log("onStartRecordBtnClick " + RecordTitle.text + ":" + RecordDescription.text); if (_eItf.IsSessionCreated) @@ -300,17 +381,11 @@ public void onStartRecordBtnClick() { } } - /// - /// start a record - /// public void onStopRecordBtnClick() { Debug.Log("onStopRecordBtnClick"); _eItf.StopRecord(); } - /// - /// inject marker - /// public void onInjectMarkerBtnClick() { Debug.Log("onInjectMarkerBtnClick " + MarkerValue.text + ":" + MarkerLabel.text); String markerValue = MarkerValue.text; @@ -324,9 +399,6 @@ public void onInjectMarkerBtnClick() { _eItf.InjectMarker(markerLabel, markerValue); } - /// - /// subscribe data stream - /// public void onSubscribeBtnClick() { Debug.Log("onSubscribeBtnClick: " + _eItf.IsSessionCreated + ": " + GetStreamsList().Count); if (_eItf.IsSessionCreated) @@ -345,9 +417,6 @@ public void onSubscribeBtnClick() { } } - /// - /// un-subscribe data - /// public void onUnsubscribeBtnClick() { Debug.Log("onUnsubscribeBtnClick"); if (GetStreamsList().Count == 0) { @@ -364,7 +433,7 @@ public void onUnsubscribeBtnClick() { /// public void onLoadProfileBtnClick() { Debug.Log("onLoadProfileBtnClick " + ProfileName.text); - _bciGameItf.CreatePlayer(ProfileName.text); + _eItf.LoadProfile(ProfileName.text); } /// @@ -387,52 +456,57 @@ public void onSaveProfileBtnClick() { /// start a mental command training action /// public void onStartMCTrainingBtnClick() { - - _bciGameItf.StartTraining(ActionNameList.captionText.text); + Debug.Log("onStartMCTrainingBtnClick " + ActionNameList.captionText.text); + _eItf.StartMCTraining(ActionNameList.captionText.text); } /// /// accept a mental command training /// public void onAcceptMCTrainingBtnClick() { - _bciGameItf.AcceptTraining(); + Debug.Log("onAcceptMCTrainingBtnClick"); + _eItf.AcceptMCTraining(); } /// /// reject a mental command training /// public void onRejectMCTrainingBtnClick() { - _bciGameItf.RejectTraining(); + Debug.Log("onRejectMCTrainingBtnClick"); + _eItf.RejectMCTraining(); } /// /// erase a mental command training /// public void onEraseMCTrainingBtnClick() { - - _bciGameItf.EraseDataForMCTrainingAction(ActionNameList.captionText.text); + Debug.Log("onEraseMCTrainingBtnClick"); + _eItf.EraseMCTraining(ActionNameList.captionText.text); } - void OnApplicationQuit() { Debug.Log("Application ending after " + Time.time + " seconds"); - _bciGameItf.Stop(); + if (_isEmotivUnityItfInitialized) + _eItf.Stop(); } private void CheckButtonsInteractable() { - if (!_eItf.IsAuthorizedOK) - return; + Button signInBtn = GameObject.Find("SessionPart").transform.Find("signInBtn").GetComponent