From fe8edbaa89d8e936cb9ffe94998617645f25c98f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+Geri8@users.noreply.github.com> Date: Fri, 2 Apr 2021 16:48:59 +0200 Subject: [PATCH 01/28] Add files via upload --- Tools/Editor/ToolsEditor.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tools/Editor/ToolsEditor.cs b/Tools/Editor/ToolsEditor.cs index 9e6dc73..a7fe40a 100644 --- a/Tools/Editor/ToolsEditor.cs +++ b/Tools/Editor/ToolsEditor.cs @@ -1,3 +1,4 @@ +#if UNITY_EDITOR using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -531,3 +532,4 @@ public class ToolsEditor{ #endregion #endif } +#endif From 1e9a1a557ca35bf853bb34c701da7fb87adff964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+Geri8@users.noreply.github.com> Date: Fri, 2 Apr 2021 16:49:53 +0200 Subject: [PATCH 02/28] Update package.json --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5f3823b..79a0b24 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.geri.simpletools", - "version": "1.0.1", + "version": "1.0.2", "displayName": "Simple Tools", "description": "This package contains simple tools to use in your project.", "unity": "2018.4", @@ -20,4 +20,4 @@ "url": "https://geri8.itch.io/" }, "type": "commonjs" -} \ No newline at end of file +} From f7c4067db49fc21f85188bccdf025774f46225cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+GerardGascon@users.noreply.github.com> Date: Wed, 9 Jun 2021 17:37:56 +0200 Subject: [PATCH 03/28] Updated README file --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 854060e..c9fa094 100644 --- a/README.md +++ b/README.md @@ -21,11 +21,11 @@ First install the TextMeshPro and Cinemachine into your Unity project ### Git Installation (Best way to get latest version) -If you have git in your computer, you can open Package Manager inside Unity, select "Add package from Git url...", and paste link [https://github.com/Geri8/SimpleTools.git](https://github.com/Geri8/SimpleTools.git) +If you have git in your computer, you can open Package Manager inside Unity, select "Add package from Git url...", and paste link [https://github.com/GerardGascon/SimpleTools.git](https://github.com/GerardGascon/SimpleTools.git) or -Open the manifest.json file of your Unity project. Add "com.geri.simpletools": "[https://github.com/Geri8/SimpleTools.git](https://github.com/Geri8/SimpleTools.git)" +Open the manifest.json file of your Unity project. Add "com.geri.simpletools": "[https://github.com/GerardGascon/SimpleTools.git](https://github.com/GerardGascon/SimpleTools.git)" ### Manual Installation From 750d7f6b8810cf6ecab655cd4e2ee25cedb1a69b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+GerardGascon@users.noreply.github.com> Date: Fri, 11 Jun 2021 19:34:49 +0200 Subject: [PATCH 04/28] Added Timer New version featuring a timer --- README.md | 4 +- Tools/AudioManager/Sounds.cs | 2 +- Tools/DialogueSystem/Dialogue.cs | 2 +- Tools/DialogueSystem/TMP_Animated.cs | 15 ++++-- Tools/Editor/ToolsEditor.cs | 24 ++++----- Tools/ObjectPooler/Pool.cs | 2 +- Tools/Timer.meta | 8 +++ Tools/Timer/Timer.cs | 79 ++++++++++++++++++++++++++++ Tools/Timer/Timer.cs.meta | 11 ++++ Tools/Timer/TimerType.cs | 7 +++ Tools/Timer/TimerType.cs.meta | 11 ++++ Tools/Timer/TimerUtility.cs | 29 ++++++++++ Tools/Timer/TimerUtility.cs.meta | 11 ++++ package.json | 4 +- 14 files changed, 186 insertions(+), 23 deletions(-) create mode 100644 Tools/Timer.meta create mode 100644 Tools/Timer/Timer.cs create mode 100644 Tools/Timer/Timer.cs.meta create mode 100644 Tools/Timer/TimerType.cs create mode 100644 Tools/Timer/TimerType.cs.meta create mode 100644 Tools/Timer/TimerUtility.cs create mode 100644 Tools/Timer/TimerUtility.cs.meta diff --git a/README.md b/README.md index c9fa094..854060e 100644 --- a/README.md +++ b/README.md @@ -21,11 +21,11 @@ First install the TextMeshPro and Cinemachine into your Unity project ### Git Installation (Best way to get latest version) -If you have git in your computer, you can open Package Manager inside Unity, select "Add package from Git url...", and paste link [https://github.com/GerardGascon/SimpleTools.git](https://github.com/GerardGascon/SimpleTools.git) +If you have git in your computer, you can open Package Manager inside Unity, select "Add package from Git url...", and paste link [https://github.com/Geri8/SimpleTools.git](https://github.com/Geri8/SimpleTools.git) or -Open the manifest.json file of your Unity project. Add "com.geri.simpletools": "[https://github.com/GerardGascon/SimpleTools.git](https://github.com/GerardGascon/SimpleTools.git)" +Open the manifest.json file of your Unity project. Add "com.geri.simpletools": "[https://github.com/Geri8/SimpleTools.git](https://github.com/Geri8/SimpleTools.git)" ### Manual Installation diff --git a/Tools/AudioManager/Sounds.cs b/Tools/AudioManager/Sounds.cs index 366dc67..9f9a5e4 100644 --- a/Tools/AudioManager/Sounds.cs +++ b/Tools/AudioManager/Sounds.cs @@ -1,7 +1,7 @@ using UnityEngine; using UnityEngine.Audio; -[CreateAssetMenu(fileName = "Sounds", menuName = "Tools/Sounds", order = 0)] +[CreateAssetMenu(fileName = "Sounds", menuName = "Simple Tools/Sounds", order = 11)] public class Sounds : ScriptableObject{ [Tooltip("The music mixer.")] diff --git a/Tools/DialogueSystem/Dialogue.cs b/Tools/DialogueSystem/Dialogue.cs index 6df4ba6..b7674d0 100644 --- a/Tools/DialogueSystem/Dialogue.cs +++ b/Tools/DialogueSystem/Dialogue.cs @@ -1,6 +1,6 @@ using UnityEngine; -[CreateAssetMenu(fileName = "New Character", menuName = "Tools/Character", order = 0)] +[CreateAssetMenu(fileName = "New Character", menuName = "Simple Tools/Character", order = 11)] public class Dialogue : ScriptableObject{ public bool displayName; diff --git a/Tools/DialogueSystem/TMP_Animated.cs b/Tools/DialogueSystem/TMP_Animated.cs index b85b257..904041b 100644 --- a/Tools/DialogueSystem/TMP_Animated.cs +++ b/Tools/DialogueSystem/TMP_Animated.cs @@ -8,12 +8,17 @@ namespace TMPro{ public class TMP_Animated : TextMeshProUGUI{ - float speed; + float speed = 20; public TextRevealEvent onTextReveal; public DialogueEvent onDialogueFinish; - public void ReadText(string newText){ + void Update(){ + /*if(Application.isPlaying) + this.Animate();*/ + } + + public void ReadText(string newText){ text = string.Empty; string[] subTexts = newText.Split('<', '>'); @@ -27,7 +32,7 @@ namespace TMPro{ } bool isCustomTag(string tag){ - return tag.StartsWith("speed=") || tag.StartsWith("pause="); + return tag.StartsWith("speed=") || tag.StartsWith("pause=") || tag.StartsWith("wave") || tag.StartsWith("rainbow") || tag.StartsWith("shake"); } text = displayText; @@ -45,7 +50,9 @@ namespace TMPro{ onTextReveal.Invoke(subTexts[subCounter][visibleCounter]); visibleCounter++; maxVisibleCharacters++; - yield return new WaitForSeconds(1f / speed); + //this.Animate(); + + yield return new WaitForSeconds(text[maxVisibleCharacters - 1] == ' ' ? 0 : (1f / speed)); } visibleCounter = 0; } diff --git a/Tools/Editor/ToolsEditor.cs b/Tools/Editor/ToolsEditor.cs index a7fe40a..b28a17b 100644 --- a/Tools/Editor/ToolsEditor.cs +++ b/Tools/Editor/ToolsEditor.cs @@ -1,4 +1,3 @@ -#if UNITY_EDITOR using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -14,13 +13,13 @@ using System; public class ToolsEditor{ - [MenuItem("GameObject/Tools/AudioManager", false, 10)] + [MenuItem("GameObject/Simple Tools/AudioManager", false, 10)] static void CreateAudioManager(){ GameObject audioManager = new GameObject("AudioManager"); audioManager.AddComponent(); } - [MenuItem("GameObject/Tools/Dialogue System", false, 10)] + [MenuItem("GameObject/Simple Tools/Dialogue System", false, 10)] static void CreateDialogueSystem(){ GameObject dialogueCanvas = new GameObject("DialogueCanvas"); dialogueCanvas.AddComponent(); @@ -51,7 +50,7 @@ public class ToolsEditor{ dialogueSystem.nameField = name; } - [MenuItem("GameObject/Tools/Camera Trigger/2D", false, 10)] + [MenuItem("GameObject/Simple Tools/Camera Trigger/2D", false, 10)] static void CreateCameraTrigger2D(){ GameObject cameraTrigger = new GameObject("CameraTrigger2D"); cameraTrigger.AddComponent(); @@ -64,7 +63,7 @@ public class ToolsEditor{ cam.m_Lens.Orthographic = true; } - [MenuItem("GameObject/Tools/Camera Trigger/3D", false, 10)] + [MenuItem("GameObject/Simple Tools/Camera Trigger/3D", false, 10)] static void CreateCameraTrigger3D(){ GameObject cameraTrigger = new GameObject("CameraTrigger3D"); cameraTrigger.AddComponent(); @@ -78,7 +77,7 @@ public class ToolsEditor{ } #if CINEMACHINE_271_OR_NEWER - [MenuItem("GameObject/Tools/ScreenShake Camera/2D", false, 10)] + [MenuItem("GameObject/Simple Tools/ScreenShake Camera/2D", false, 10)] static void CreateScreenShakeCamera2d(){ GameObject screenShakeCamera = new GameObject("ScreenShakeCamera"); CinemachineVirtualCamera vCam = screenShakeCamera.AddComponent(); @@ -92,7 +91,7 @@ public class ToolsEditor{ shake.m_AmplitudeGain = 0f; shake.m_FrequencyGain = 1f; } - [MenuItem("GameObject/Tools/ScreenShake Camera/3D", false, 10)] + [MenuItem("GameObject/Simple Tools/ScreenShake Camera/3D", false, 10)] static void CreateScreenShakeCamera3d(){ GameObject screenShakeCamera = new GameObject("ScreenShakeCamera"); CinemachineVirtualCamera vCam = screenShakeCamera.AddComponent(); @@ -107,7 +106,7 @@ public class ToolsEditor{ shake.m_FrequencyGain = 1f; } #else - [MenuItem("GameObject/Tools/ScreenShake Camera", false, 10)] + [MenuItem("GameObject/Simple Tools/ScreenShake Camera", false, 10)] static void CreateScreenShakeCamera2d(){ GameObject screenShakeCamera = new GameObject("ScreenShakeCamera"); CinemachineVirtualCamera vCam = screenShakeCamera.AddComponent(); @@ -122,7 +121,8 @@ public class ToolsEditor{ } #endif - [MenuItem("Assets/Create/Tools/Create Loading Scene")] + [MenuItem("Assets/Create/Simple Tools/Create Loading Scene")] + [MenuItem("Simple Tools/Create Loading Scene")] static void CreateLoadingScene(){ EditorSceneManager.SaveOpenScenes(); @@ -163,7 +163,7 @@ public class ToolsEditor{ progressBarTransform.anchoredPosition = Vector2.zero; progressBarTransform.sizeDelta = new Vector2Int(900, 20); - progressBar.sprite = (Sprite)AssetDatabase.LoadAssetAtPath("Packages/com.geri.simpletools/Tools/Editor/Square.png", typeof(Sprite)); + progressBar.sprite = (Sprite)AssetDatabase.LoadAssetAtPath("Packages/com.geri.simpletools/Simple Tools/Editor/Square.png", typeof(Sprite)); progressBar.type = Image.Type.Filled; progressBar.fillMethod = Image.FillMethod.Horizontal; progressBar.fillOrigin = (int)Image.OriginHorizontal.Left; @@ -172,7 +172,8 @@ public class ToolsEditor{ } #if UNITY_2019_3_OR_NEWER - [MenuItem("Assets/Create/Tools/Create Menu Scene")] + [MenuItem("Assets/Create/Simple Tools/Create Menu Scene")] + [MenuItem("Simple Tools/Create Menu Scene")] static void CreateMenuScene(){ EditorSceneManager.SaveOpenScenes(); @@ -532,4 +533,3 @@ public class ToolsEditor{ #endregion #endif } -#endif diff --git a/Tools/ObjectPooler/Pool.cs b/Tools/ObjectPooler/Pool.cs index 1e99a63..50ed704 100644 --- a/Tools/ObjectPooler/Pool.cs +++ b/Tools/ObjectPooler/Pool.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using UnityEngine; -[CreateAssetMenu(fileName = "New Pool", menuName = "Tools/Pool", order = 0)] +[CreateAssetMenu(fileName = "New Pool", menuName = "Simple Tools/Pool", order = 11)] public class Pool : ScriptableObject{ public List pools; diff --git a/Tools/Timer.meta b/Tools/Timer.meta new file mode 100644 index 0000000..4762356 --- /dev/null +++ b/Tools/Timer.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b904c9938b1a3df4e83b1103e3085400 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tools/Timer/Timer.cs b/Tools/Timer/Timer.cs new file mode 100644 index 0000000..0524682 --- /dev/null +++ b/Tools/Timer/Timer.cs @@ -0,0 +1,79 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using System; +using TMPro; + +namespace SimpleTools.Timer{ + public class Timer : MonoBehaviour{ + + float elapsedTime; + public float ElapsedTime { get { return elapsedTime; } } + bool isPaused; + public bool IsPaused { get { return isPaused; } } + TimeSpan timePlaying; + public TimeSpan TimePlaying { get { return timePlaying; } } + TMP_Text timer; + public TMP_Text TimerText { get { return timer; } } + TimerType timerType; + public TimerType TimerType { get { return timerType; } } + + public void Setup(float elapsedTime, bool isPaused, TimeSpan timePlaying, TMP_Text timer, TimerType timerType, string text){ + this.elapsedTime = elapsedTime; + this.isPaused = isPaused; + this.timePlaying = timePlaying; + this.timer = timer; + this.timerType = timerType; + timer.text = text; + } + + IEnumerator UpdateTimer(){ + while (!isPaused){ + if(timerType == TimerType.Clock){ + timer.text = DateTime.Now.ToString("HH:mm:ss"); + }else{ + switch (timerType){ + case TimerType.Countdown: + elapsedTime -= Time.deltaTime; + if(elapsedTime < 0f){ + elapsedTime = 0f; + isPaused = true; + } + break; + case TimerType.Stopwatch: + elapsedTime += Time.deltaTime; + break; + } + timePlaying = TimeSpan.FromSeconds(elapsedTime); + timer.text = timePlaying.ToString("m':'ss'.'ff"); + } + yield return null; + } + } + + public void Play(){ + isPaused = false; + StartCoroutine(UpdateTimer()); + } + + public void Stop(){ + isPaused = true; + } + + public void ResetTimer(){ + isPaused = true; + elapsedTime = 0f; + timePlaying = TimeSpan.FromSeconds(elapsedTime); + timer.text = timePlaying.ToString("m':'ss'.'ff"); + } + + public void Restart(){ + isPaused = false; + elapsedTime = 0f; + timePlaying = TimeSpan.FromSeconds(elapsedTime); + timer.text = timePlaying.ToString("m':'ss'.'ff"); + StopAllCoroutines(); + StartCoroutine(UpdateTimer()); + } + } +} diff --git a/Tools/Timer/Timer.cs.meta b/Tools/Timer/Timer.cs.meta new file mode 100644 index 0000000..af559b2 --- /dev/null +++ b/Tools/Timer/Timer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6daeed0a6935f484f85fc0ec1871344f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tools/Timer/TimerType.cs b/Tools/Timer/TimerType.cs new file mode 100644 index 0000000..a758dbb --- /dev/null +++ b/Tools/Timer/TimerType.cs @@ -0,0 +1,7 @@ +namespace SimpleTools.Timer{ + public enum TimerType{ + Countdown, + Stopwatch, + Clock + } +} diff --git a/Tools/Timer/TimerType.cs.meta b/Tools/Timer/TimerType.cs.meta new file mode 100644 index 0000000..3de6eec --- /dev/null +++ b/Tools/Timer/TimerType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f285456223780f946b49c6131d493c01 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tools/Timer/TimerUtility.cs b/Tools/Timer/TimerUtility.cs new file mode 100644 index 0000000..90ba52e --- /dev/null +++ b/Tools/Timer/TimerUtility.cs @@ -0,0 +1,29 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using System; +using TMPro; + +namespace SimpleTools.Timer{ + public static class TimerUtility { + public static Timer SetupTimer(this TMP_Text container, TimerType timerType, float countdownTime = 60f){ + Timer t = container.gameObject.AddComponent(); + float elapsedTime = 0f; + string text = string.Empty; + TimeSpan timePlaying = TimeSpan.Zero; + switch (timerType){ + case TimerType.Countdown: + elapsedTime = countdownTime; + timePlaying = TimeSpan.FromSeconds(elapsedTime); + text = timePlaying.ToString("m':'ss'.'ff"); + break; + case TimerType.Clock: + text = DateTime.Now.ToString("HH:mm:ss"); + break; + } + t.Setup(elapsedTime, true, timePlaying, container, timerType, text); + + return t; + } + } +} diff --git a/Tools/Timer/TimerUtility.cs.meta b/Tools/Timer/TimerUtility.cs.meta new file mode 100644 index 0000000..1b46b33 --- /dev/null +++ b/Tools/Timer/TimerUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 38076483429281e438cee653b26bb03d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/package.json b/package.json index 79a0b24..c13a739 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.geri.simpletools", - "version": "1.0.2", + "version": "1.1.0", "displayName": "Simple Tools", "description": "This package contains simple tools to use in your project.", "unity": "2018.4", @@ -20,4 +20,4 @@ "url": "https://geri8.itch.io/" }, "type": "commonjs" -} +} \ No newline at end of file From a4c26426e5d519e39eea9a3adc53581127bb4b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+GerardGascon@users.noreply.github.com> Date: Sat, 12 Jun 2021 10:36:38 +0200 Subject: [PATCH 05/28] Fixed some timer bugs Timer now has a mode for unscaled time FIXED: Countdown now resets properly --- Tools/Timer/Timer.cs | 32 ++++++++++++++++++++++++++------ Tools/Timer/TimerUpdate.cs | 6 ++++++ Tools/Timer/TimerUpdate.cs.meta | 11 +++++++++++ Tools/Timer/TimerUtility.cs | 11 +++++++++-- package.json | 2 +- 5 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 Tools/Timer/TimerUpdate.cs create mode 100644 Tools/Timer/TimerUpdate.cs.meta diff --git a/Tools/Timer/Timer.cs b/Tools/Timer/Timer.cs index 0524682..49a7e28 100644 --- a/Tools/Timer/Timer.cs +++ b/Tools/Timer/Timer.cs @@ -17,13 +17,21 @@ namespace SimpleTools.Timer{ public TMP_Text TimerText { get { return timer; } } TimerType timerType; public TimerType TimerType { get { return timerType; } } + TimerUpdate timerUpdate; + public TimerUpdate TimerUpdate { get { return timerUpdate; } } - public void Setup(float elapsedTime, bool isPaused, TimeSpan timePlaying, TMP_Text timer, TimerType timerType, string text){ - this.elapsedTime = elapsedTime; + float defaultTime; + + /// + /// Setup the timer + /// + public void Setup(float elapsedTime, bool isPaused, TimeSpan timePlaying, TMP_Text timer, TimerType timerType, TimerUpdate timerUpdate, string text){ + this.elapsedTime = defaultTime = elapsedTime; this.isPaused = isPaused; this.timePlaying = timePlaying; this.timer = timer; this.timerType = timerType; + this.timerUpdate = timerUpdate; timer.text = text; } @@ -34,14 +42,14 @@ namespace SimpleTools.Timer{ }else{ switch (timerType){ case TimerType.Countdown: - elapsedTime -= Time.deltaTime; + elapsedTime -= timerUpdate == TimerUpdate.UnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime; if(elapsedTime < 0f){ elapsedTime = 0f; isPaused = true; } break; case TimerType.Stopwatch: - elapsedTime += Time.deltaTime; + elapsedTime += timerUpdate == TimerUpdate.UnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime; break; } timePlaying = TimeSpan.FromSeconds(elapsedTime); @@ -51,25 +59,37 @@ namespace SimpleTools.Timer{ } } + /// + /// Play or resume the timer + /// public void Play(){ isPaused = false; StartCoroutine(UpdateTimer()); } + /// + /// Pause the timer + /// public void Stop(){ isPaused = true; } + /// + /// Pause and sets the time to the defaultOne + /// public void ResetTimer(){ isPaused = true; - elapsedTime = 0f; + elapsedTime = defaultTime; timePlaying = TimeSpan.FromSeconds(elapsedTime); timer.text = timePlaying.ToString("m':'ss'.'ff"); } + /// + /// Restarts the timer + /// public void Restart(){ isPaused = false; - elapsedTime = 0f; + elapsedTime = defaultTime; timePlaying = TimeSpan.FromSeconds(elapsedTime); timer.text = timePlaying.ToString("m':'ss'.'ff"); StopAllCoroutines(); diff --git a/Tools/Timer/TimerUpdate.cs b/Tools/Timer/TimerUpdate.cs new file mode 100644 index 0000000..8a95b13 --- /dev/null +++ b/Tools/Timer/TimerUpdate.cs @@ -0,0 +1,6 @@ +namespace SimpleTools.Timer{ + public enum TimerUpdate{ + ScaledTime, + UnscaledTime, + } +} diff --git a/Tools/Timer/TimerUpdate.cs.meta b/Tools/Timer/TimerUpdate.cs.meta new file mode 100644 index 0000000..930e415 --- /dev/null +++ b/Tools/Timer/TimerUpdate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 977b7b3a05b17c04da63124856e9ff6f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tools/Timer/TimerUtility.cs b/Tools/Timer/TimerUtility.cs index 90ba52e..365e412 100644 --- a/Tools/Timer/TimerUtility.cs +++ b/Tools/Timer/TimerUtility.cs @@ -6,7 +6,14 @@ using TMPro; namespace SimpleTools.Timer{ public static class TimerUtility { - public static Timer SetupTimer(this TMP_Text container, TimerType timerType, float countdownTime = 60f){ + /// + /// Setup the timer + /// + /// TMPro object that will contain the timer + /// What type of timer will it be (Countdown, Stopwatch, Clock) + /// The time that will have in case it is a countdown timer + /// + public static Timer SetupTimer(this TMP_Text container, TimerType timerType, TimerUpdate timerUpdate, float countdownTime = 60f){ Timer t = container.gameObject.AddComponent(); float elapsedTime = 0f; string text = string.Empty; @@ -21,7 +28,7 @@ namespace SimpleTools.Timer{ text = DateTime.Now.ToString("HH:mm:ss"); break; } - t.Setup(elapsedTime, true, timePlaying, container, timerType, text); + t.Setup(elapsedTime, true, timePlaying, container, timerType, timerUpdate, text); return t; } diff --git a/package.json b/package.json index c13a739..f25e252 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.geri.simpletools", - "version": "1.1.0", + "version": "1.1.1", "displayName": "Simple Tools", "description": "This package contains simple tools to use in your project.", "unity": "2018.4", From ae7d486799e9f8c699380e56778c64cfbac57135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+GerardGascon@users.noreply.github.com> Date: Sat, 12 Jun 2021 10:40:01 +0200 Subject: [PATCH 06/28] Fixed some timer bugs Timer now has a mode for unscaled time FIXED: Countdown now resets properly From d88484754843e9988c9e19aacf222db0a1b3952f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+GerardGascon@users.noreply.github.com> Date: Sun, 13 Jun 2021 15:52:12 +0200 Subject: [PATCH 07/28] Probably fixed build errors --- Tools/Editor/ToolsEditor.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tools/Editor/ToolsEditor.cs b/Tools/Editor/ToolsEditor.cs index b28a17b..acadbd3 100644 --- a/Tools/Editor/ToolsEditor.cs +++ b/Tools/Editor/ToolsEditor.cs @@ -1,3 +1,4 @@ +#if UNITY_EDITOR using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -533,3 +534,4 @@ public class ToolsEditor{ #endregion #endif } +#endif From a90a0ab215fd86f5beb31926aa02fe902301271b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+GerardGascon@users.noreply.github.com> Date: Sun, 13 Jun 2021 15:52:36 +0200 Subject: [PATCH 08/28] Update package.json --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f25e252..8a5c997 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.geri.simpletools", - "version": "1.1.1", + "version": "1.1.2", "displayName": "Simple Tools", "description": "This package contains simple tools to use in your project.", "unity": "2018.4", @@ -20,4 +20,4 @@ "url": "https://geri8.itch.io/" }, "type": "commonjs" -} \ No newline at end of file +} From a076495090e22f1ad04bcd0f086f727b3d61905c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+GerardGascon@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:16:23 +0200 Subject: [PATCH 09/28] Update Timer.cs --- Tools/Timer/Timer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/Timer/Timer.cs b/Tools/Timer/Timer.cs index 49a7e28..6f03df5 100644 --- a/Tools/Timer/Timer.cs +++ b/Tools/Timer/Timer.cs @@ -75,7 +75,7 @@ namespace SimpleTools.Timer{ } /// - /// Pause and sets the time to the defaultOne + /// Pause and sets the time to the default one /// public void ResetTimer(){ isPaused = true; From 91604d39466d6ba1a7530d899d515e7befc52983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+GerardGascon@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:18:03 +0200 Subject: [PATCH 10/28] Updated README --- README.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 854060e..c45a3ab 100644 --- a/README.md +++ b/README.md @@ -21,11 +21,11 @@ First install the TextMeshPro and Cinemachine into your Unity project ### Git Installation (Best way to get latest version) -If you have git in your computer, you can open Package Manager inside Unity, select "Add package from Git url...", and paste link [https://github.com/Geri8/SimpleTools.git](https://github.com/Geri8/SimpleTools.git) +If you have git in your computer, you can open Package Manager inside Unity, select "Add package from Git url...", and paste link [https://github.com/GerardGascon/SimpleTools.git](https://github.com/GerardGascon/SimpleTools.git) or -Open the manifest.json file of your Unity project. Add "com.geri.simpletools": "[https://github.com/Geri8/SimpleTools.git](https://github.com/Geri8/SimpleTools.git)" +Open the manifest.json file of your Unity project. Add "com.geri.simpletools": "[https://github.com/GerardGascon/SimpleTools.git](https://github.com/GerardGascon/SimpleTools.git)" ### Manual Installation @@ -98,6 +98,24 @@ Loader.Load("Scene"); //Loads a scene with a specific name ScreenShake.Shake(1f, .25f); //Shakes the camera with an intensity and duration ``` +### Timer + +```csharp +using SimpleTools.Timer; + +//Setup a stopwatch that updates at an unscaled time +Timer timer = textMeshProText.SetupTimer(TimerType.Stopwatch, TimerUpdate.UnscaledTime); +//Setup a clock +Timer timer = textMeshProText.SetupTimer(TimerType.Clock, TimerUpdate.UnscaledTime); +//Setup a countdown with the default time of 60 seconds +Timer timer = textMeshProText.SetupTimer(TimerType.Countdown, TimerUpdate.UnscaledTime, 60f); + +timer.Play(); //Play or resume the timer +timer.Stop(); //Pause the timer +timer.ResetTimer(); //Pause and sets the time to the default one +timer.Restart(); //Restarts the timer +``` + ### Editor You can easily set up some things by right clicking in your Project Tab and then selecting Tools and clicking on the one you want to create. From 95bad523b91081a7b9ffa574fb7603fd56492a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+GerardGascon@users.noreply.github.com> Date: Sun, 13 Mar 2022 22:23:46 +0100 Subject: [PATCH 11/28] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c45a3ab..6e63697 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ This package will be updated once I find another useful tool or someone suggest - Basic menu with **music and SFX sliders** as well as **resolution and quality dropdowns.** - An **object pooler** with the ability to create pools with an undetermined size. - A basic **scene manager** with a loading screen with progress bar. +- A **timer** that is displayed inside a TextMeshPro object. All of that comes with some editor menu items for creating all of that as fast as possible. @@ -120,4 +121,4 @@ timer.Restart(); //Restarts the timer You can easily set up some things by right clicking in your Project Tab and then selecting Tools and clicking on the one you want to create. -Also you can right click in the Hierarchy for easily creating some GameObjects with the Tools in it. \ No newline at end of file +Also you can right click in the Hierarchy for easily creating some GameObjects with the Tools in it. From 0e8b8b183527df6055feb8d6f4636c3802e164f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+GerardGascon@users.noreply.github.com> Date: Thu, 15 Sep 2022 17:27:28 +0200 Subject: [PATCH 12/28] Reworked the dialogue system Now the dialogue can use tags to add special effects Reorganized project structure, updating may require adding some using statements --- README.md | 24 +- Tools/AudioManager/AudioManager.cs | 491 +++++----- Tools/AudioManager/Sounds.cs | 77 +- Tools/Cinemachine/CMCameraTrigger.cs | 64 +- Tools/Cinemachine/ScreenShake.cs | 60 +- Tools/DialogueSystem/Dialogue.cs | 22 +- Tools/DialogueSystem/DialogueManager.cs | 112 +++ Tools/DialogueSystem/DialogueManager.cs.meta | 11 + Tools/DialogueSystem/DialogueUtility.cs | 152 +++ Tools/DialogueSystem/DialogueUtility.cs.meta | 11 + .../DialogueSystem/DialogueVertexAnimator.cs | 262 ++++++ .../DialogueVertexAnimator.cs.meta | 11 + Tools/Editor/ToolsEditor.cs | 873 +++++++++--------- Tools/Menu/MenuController.cs | 171 ++-- Tools/MonobehaviourExtensions.cs | 12 + Tools/MonobehaviourExtensions.cs.meta | 11 + Tools/ObjectPooler/IPooledObject.cs | 8 +- Tools/ObjectPooler/Pool.cs | 26 +- Tools/ObjectPooler/Pooler.cs | 578 ++++++------ Tools/SceneManager/Loader.cs | 102 +- Tools/SceneManager/LoaderCallback.cs | 18 +- Tools/SceneManager/LoadingProgressBar.cs | 24 +- Tools/Timer/Timer.cs | 2 +- Tools/Timer/TimerUtility.cs | 52 +- package.json | 4 +- 25 files changed, 1912 insertions(+), 1266 deletions(-) create mode 100644 Tools/DialogueSystem/DialogueManager.cs create mode 100644 Tools/DialogueSystem/DialogueManager.cs.meta create mode 100644 Tools/DialogueSystem/DialogueUtility.cs create mode 100644 Tools/DialogueSystem/DialogueUtility.cs.meta create mode 100644 Tools/DialogueSystem/DialogueVertexAnimator.cs create mode 100644 Tools/DialogueSystem/DialogueVertexAnimator.cs.meta create mode 100644 Tools/MonobehaviourExtensions.cs create mode 100644 Tools/MonobehaviourExtensions.cs.meta diff --git a/README.md b/README.md index 6e63697..e979e03 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,6 @@ This package will be updated once I find another useful tool or someone suggest - Basic menu with **music and SFX sliders** as well as **resolution and quality dropdowns.** - An **object pooler** with the ability to create pools with an undetermined size. - A basic **scene manager** with a loading screen with progress bar. -- A **timer** that is displayed inside a TextMeshPro object. All of that comes with some editor menu items for creating all of that as fast as possible. @@ -37,6 +36,8 @@ Download latest package from the Release section Import SimpleTools.unitypackage ### AudioManager ```csharp +using SimpleTools.AudioManager; + AudioManager.instance.Play("Name"); //Plays the sound with that name AudioManager.instance.Play("Name", 1f); //Starts playing the sound "Name" in 1 second AudioManager.instance.PlayOneShot("Name"); //Plays one shot of that sound (Useful for repeated sounds) @@ -63,6 +64,8 @@ AudioManager.instance.FadeMutedOut("Name", 1f); //Fade Out a sound without stopp The SpawnFromPool function always return a GameObject ```csharp +using SimpleTools.ObjectPooler; + Pool pool; //The pool scriptable object goes here Pooler.CreatePools(pool); //Create the pool, without creating it you cannot spawn it Pool[] pools; @@ -82,13 +85,28 @@ Pooler.SpawnFromPool("Name", Vector3.zero, Quaternion.identity, transform, true) The Dialogue function returns a bool (true if it's talking, false if it has ended) ```csharp +using SimpleTools.DialogueSystem; + Dialogue dialogue; //The dialogue scriptable object goes here DialogueSystem.instance.Dialogue(dialogue); //Start/Continue the dialogue +DialogueSystem.instance.Dialogue(dialogue, "Sound1", "Sound2"); //Start/Continue the dialogue with a random set of sounds for the text reveal ``` +Text commands: + +| | Sets font color within tags | +| --- | --- | +| | Sets font size within tags | +| | Draws a sprite from the TextMeshPro | +| | Pauses during a period of time | +| | Reproduces an animation | +| | Changes reveal speed | + ### SceneManager ```csharp +using SimpleTools.SceneManagement; + Loader.Load(0); //Loads a scene with a specific build index Loader.Load("Scene"); //Loads a scene with a specific name ``` @@ -96,6 +114,8 @@ Loader.Load("Scene"); //Loads a scene with a specific name ### ScreenShake ```csharp +using SimpleTools.Cinemachine; + ScreenShake.Shake(1f, .25f); //Shakes the camera with an intensity and duration ``` @@ -121,4 +141,4 @@ timer.Restart(); //Restarts the timer You can easily set up some things by right clicking in your Project Tab and then selecting Tools and clicking on the one you want to create. -Also you can right click in the Hierarchy for easily creating some GameObjects with the Tools in it. +Also you can right click in the Hierarchy for easily creating some GameObjects with the Tools in it. \ No newline at end of file diff --git a/Tools/AudioManager/AudioManager.cs b/Tools/AudioManager/AudioManager.cs index 4b6c3f5..7ce5230 100644 --- a/Tools/AudioManager/AudioManager.cs +++ b/Tools/AudioManager/AudioManager.cs @@ -2,261 +2,270 @@ using UnityEngine; using System; -public class AudioManager : MonoBehaviour{ +namespace SimpleTools.AudioManager { + public class AudioManager : MonoBehaviour { - public static AudioManager instance; + public static AudioManager instance; - [SerializeField] Sounds soundList = default; + [SerializeField] Sounds soundList = default; - void Awake(){ - if(instance == null){ - instance = this; - }else{ - Destroy(gameObject); - return; - } - DontDestroyOnLoad(gameObject); + void Awake() { + if (instance == null) { + instance = this; + } else { + Destroy(gameObject); + return; + } + DontDestroyOnLoad(gameObject); - foreach(Sounds.List s in soundList.sounds){ - if(string.IsNullOrEmpty(s.name) || string.IsNullOrWhiteSpace(s.name)){ - Debug.LogWarning("The name one sound is empty"); - continue; - } + foreach (Sounds.List s in soundList.sounds) { + if (string.IsNullOrEmpty(s.name) || string.IsNullOrWhiteSpace(s.name)) { + Debug.LogWarning("The name one sound is empty"); + continue; + } - GameObject sound = new GameObject(s.name); - sound.transform.parent = transform; - s.source = sound.AddComponent(); + GameObject sound = new GameObject(s.name); + sound.transform.parent = transform; + s.source = sound.AddComponent(); - if(soundList.mainMixer && soundList.sfxMixer){ - if (s.type == Sounds.List.Type.Music) - s.source.outputAudioMixerGroup = soundList.mainMixer; - else - s.source.outputAudioMixerGroup = soundList.sfxMixer; - } + if (soundList.mainMixer && soundList.sfxMixer) { + if (s.type == Sounds.List.Type.Music) + s.source.outputAudioMixerGroup = soundList.mainMixer; + else + s.source.outputAudioMixerGroup = soundList.sfxMixer; + } - s.source.clip = s.clip; + s.source.clip = s.clip; - s.source.volume = s.volume; - s.source.pitch = s.pitch; - s.source.loop = s.loop; - } - } + s.source.volume = s.volume; + s.source.pitch = s.pitch; + s.source.loop = s.loop; + } + } - #region Play - /// Use this to play a sound with a specific name - /// It has to be in the Sound asset referenced in the AudioManager instance - /// - public void Play(string name){ - Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); - if(s == null){ - Debug.LogWarning("Sound: " + name + " not found!"); - return; - } - s.source.pitch = s.RandomPitch; - s.source.volume = s.RandomVolume; - s.source.Play(); - } - /// Use this to play a sound with a specific name and with a certain delay - /// It has to be in the Sound asset referenced in the AudioManager instance - /// - public void Play(string name, float delay){ - Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); - if (s == null){ - Debug.LogWarning("Sound: " + name + " not found!"); - return; - } - s.source.pitch = s.RandomPitch; - s.source.volume = s.RandomVolume; - s.source.PlayDelayed(delay); - } - /// Use this to play one shot of a sound with a specific name - /// It has to be in the Sound asset referenced in the AudioManager instance - /// - public void PlayOneShot(string name){ - Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); - if (s == null){ - Debug.LogWarning("Sound: " + name + " not found!"); - return; - } - s.source.pitch = s.RandomPitch; - s.source.volume = s.RandomVolume; - s.source.PlayOneShot(s.clip); - } - /// Use this to play an intro song and then start playing the song loop - /// It has to be in the Sound asset referenced in the AudioManager instance - /// - public void PlayWithIntro(string intro, string song){ - Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == intro); - if (s == null){ - Debug.LogWarning("Sound: " + intro + " not found!"); - return; - } - s.source.pitch = s.RandomPitch; - s.source.volume = s.RandomVolume; - s.source.Play(); + #region Play + /// Use this to play a sound with a specific name + /// It has to be in the Sound asset referenced in the AudioManager instance + /// + public void Play(string name) { + Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); + if (s == null) { + Debug.LogWarning("Sound: " + name + " not found!"); + return; + } + s.source.pitch = s.RandomPitch; + s.source.volume = s.RandomVolume; + s.source.Play(); + } + /// Use this to play a sound with a specific name and with a certain delay + /// It has to be in the Sound asset referenced in the AudioManager instance + /// + public void Play(string name, float delay) { + Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); + if (s == null) { + Debug.LogWarning("Sound: " + name + " not found!"); + return; + } + s.source.pitch = s.RandomPitch; + s.source.volume = s.RandomVolume; + s.source.PlayDelayed(delay); + } + /// Use this to play one shot of a sound with a specific name + /// It has to be in the Sound asset referenced in the AudioManager instance + /// + public void PlayOneShot(string name) { + Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); + if (s == null) { + Debug.LogWarning("Sound: " + name + " not found!"); + return; + } + s.source.pitch = s.RandomPitch; + s.source.volume = s.RandomVolume; + s.source.PlayOneShot(s.clip); + } + /// Use this to play an intro song and then start playing the song loop + /// It has to be in the Sound asset referenced in the AudioManager instance + /// + public void PlayWithIntro(string intro, string song) { + Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == intro); + if (s == null) { + Debug.LogWarning("Sound: " + intro + " not found!"); + return; + } + s.source.pitch = s.RandomPitch; + s.source.volume = s.RandomVolume; + s.source.Play(); - float introDuration = s.clip.length; - Play(song, introDuration); - } - #endregion - #region Pause - /// Use this to pause a sound with a specific name - /// It has to be in the Sound asset referenced in the AudioManager instance - /// - public void Pause(string name){ - Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); - if (s == null){ - Debug.LogWarning("Sound: " + name + " not found!"); - return; - } - s.source.pitch = s.RandomPitch; - s.source.volume = s.RandomVolume; - s.source.Pause(); - } - /// Use this to unpause a sound with a specific name - /// It has to be in the Sound asset referenced in the AudioManager instance - /// - public void UnPause(string name){ - Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); - if (s == null){ - Debug.LogWarning("Sound: " + name + " not found!"); - return; - } - s.source.pitch = s.RandomPitch; - s.source.volume = s.RandomVolume; - s.source.UnPause(); - } - #endregion - #region Stop - /// Use this to stop a sound with a specific name - /// It has to be in the Sound asset referenced in the AudioManager instance - /// - public void Stop(string name){ - Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); - if (s == null){ - Debug.LogWarning("Sound: " + name + " not found!"); - return; - } - s.source.pitch = s.RandomPitch; - s.source.volume = s.RandomVolume; - s.source.Stop(); - } - /// Use this to stop all the sounds - /// It has to be in the Sound asset referenced in the AudioManager instance - /// - public void StopAll(){ - foreach (Sounds.List s in soundList.sounds){ - if (s.source){ - s.source.Stop(); - } - } - } - #endregion - /// This function returns the AudioSource that contains a specific sound - /// It has to be in the Sound asset referenced in the AudioManager instance - /// - public AudioSource GetSource(string name){ - Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); - if (s == null){ - Debug.LogWarning("Sound: " + name + " not found!"); - return null; - } - return s.source; - } - #region Fades - /// Use this to start playing a sound with a fade in - /// It has to be in the Sound asset referenced in the AudioManager instance - /// - public void FadeIn(string name, float duration){ - StartCoroutine(FadeInCoroutine(name, duration)); - } - IEnumerator FadeInCoroutine(string name, float fadeTime){ - AudioSource audioSource = GetSource(name); - if (audioSource != null && !audioSource.isPlaying){ - float volume = audioSource.volume; - audioSource.volume = 0; - audioSource.Play(); - while (audioSource.volume < volume){ - audioSource.volume += Time.deltaTime / fadeTime; - yield return null; - } + float introDuration = s.clip.length; + Play(song, introDuration); + } + /// Use this to play one shot of a random sound within a list + /// They have to be in the Sound asset referenced in the AudioManager instance + /// + public void PlayRandomSound(params string[] names) { + int random = UnityEngine.Random.Range(0, names.Length); + PlayOneShot(names[random]); + } + #endregion + #region Pause + /// Use this to pause a sound with a specific name + /// It has to be in the Sound asset referenced in the AudioManager instance + /// + public void Pause(string name) { + Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); + if (s == null) { + Debug.LogWarning("Sound: " + name + " not found!"); + return; + } + s.source.pitch = s.RandomPitch; + s.source.volume = s.RandomVolume; + s.source.Pause(); + } + /// Use this to unpause a sound with a specific name + /// It has to be in the Sound asset referenced in the AudioManager instance + /// + public void UnPause(string name) { + Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); + if (s == null) { + Debug.LogWarning("Sound: " + name + " not found!"); + return; + } + s.source.pitch = s.RandomPitch; + s.source.volume = s.RandomVolume; + s.source.UnPause(); + } + #endregion + #region Stop + /// Use this to stop a sound with a specific name + /// It has to be in the Sound asset referenced in the AudioManager instance + /// + public void Stop(string name) { + Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); + if (s == null) { + Debug.LogWarning("Sound: " + name + " not found!"); + return; + } + s.source.pitch = s.RandomPitch; + s.source.volume = s.RandomVolume; + s.source.Stop(); + } + /// Use this to stop all the sounds + /// It has to be in the Sound asset referenced in the AudioManager instance + /// + public void StopAll() { + foreach (Sounds.List s in soundList.sounds) { + if (s.source) { + s.source.Stop(); + } + } + } + #endregion + /// This function returns the AudioSource that contains a specific sound + /// It has to be in the Sound asset referenced in the AudioManager instance + /// + public AudioSource GetSource(string name) { + Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); + if (s == null) { + Debug.LogWarning("Sound: " + name + " not found!"); + return null; + } + return s.source; + } + #region Fades + /// Use this to start playing a sound with a fade in + /// It has to be in the Sound asset referenced in the AudioManager instance + /// + public void FadeIn(string name, float duration) { + StartCoroutine(FadeInCoroutine(name, duration)); + } + IEnumerator FadeInCoroutine(string name, float fadeTime) { + AudioSource audioSource = GetSource(name); + if (audioSource != null && !audioSource.isPlaying) { + float volume = audioSource.volume; + audioSource.volume = 0; + audioSource.Play(); + while (audioSource.volume < volume) { + audioSource.volume += Time.deltaTime / fadeTime; + yield return null; + } - audioSource.volume = volume; - } - } - /// Use this to stop playing a sound with a fade out - /// It has to be in the Sound asset referenced in the AudioManager instance - /// - public void FadeOut(string name, float duration){ - StartCoroutine(FadeOutCoroutine(name, duration)); - } - IEnumerator FadeOutCoroutine(string name, float fadeTime){ - AudioSource audioSource = GetSource(name); + audioSource.volume = volume; + } + } + /// Use this to stop playing a sound with a fade out + /// It has to be in the Sound asset referenced in the AudioManager instance + /// + public void FadeOut(string name, float duration) { + StartCoroutine(FadeOutCoroutine(name, duration)); + } + IEnumerator FadeOutCoroutine(string name, float fadeTime) { + AudioSource audioSource = GetSource(name); - if (audioSource && audioSource.isPlaying){ - float startVolume = audioSource.volume; + if (audioSource && audioSource.isPlaying) { + float startVolume = audioSource.volume; - while (audioSource.volume > 0){ - audioSource.volume -= startVolume * Time.deltaTime / fadeTime; - yield return null; - } + while (audioSource.volume > 0) { + audioSource.volume -= startVolume * Time.deltaTime / fadeTime; + yield return null; + } - audioSource.Stop(); - audioSource.volume = startVolume; - } - } + audioSource.Stop(); + audioSource.volume = startVolume; + } + } - /// Use this to start playing a sound muted - /// It has to be in the Sound asset referenced in the AudioManager instance - /// - public void PlayMuted(string name){ - Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); - if (s == null){ - Debug.LogWarning("Sound: " + name + " not found!"); - return; - } - s.source.pitch = s.RandomPitch; - s.source.volume = 0f; - s.source.Play(); - } - /// Use this to fade in a sound that is currently muted - /// It has to be in the Sound asset referenced in the AudioManager instance - /// WARNING: If the PlayMuted hasn't been called before, this function won't work - /// - public void FadeMutedIn(string name, float duration){ - StartCoroutine(FadeMutedInCoroutine(name, duration)); - } - IEnumerator FadeMutedInCoroutine(string name, float fadeTime){ - Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); - if (s == null){ - Debug.LogWarning("Sound: " + name + " not found!"); - yield break; - } + /// Use this to start playing a sound muted + /// It has to be in the Sound asset referenced in the AudioManager instance + /// + public void PlayMuted(string name) { + Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); + if (s == null) { + Debug.LogWarning("Sound: " + name + " not found!"); + return; + } + s.source.pitch = s.RandomPitch; + s.source.volume = 0f; + s.source.Play(); + } + /// Use this to fade in a sound that is currently muted + /// It has to be in the Sound asset referenced in the AudioManager instance + /// WARNING: If the PlayMuted hasn't been called before, this function won't work + /// + public void FadeMutedIn(string name, float duration) { + StartCoroutine(FadeMutedInCoroutine(name, duration)); + } + IEnumerator FadeMutedInCoroutine(string name, float fadeTime) { + Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); + if (s == null) { + Debug.LogWarning("Sound: " + name + " not found!"); + yield break; + } - while (s.source.volume < s.volume){ - s.source.volume += Time.deltaTime / fadeTime; - yield return null; - } - s.source.volume = s.volume; - } - /// Use this to fade out a sound and keep playing that muted - /// It has to be in the Sound asset referenced in the AudioManager instance - /// - public void FadeMutedOut(string name, float duration){ - StartCoroutine(FadeMutedOutCoroutine(name, duration)); - } - IEnumerator FadeMutedOutCoroutine(string name, float fadeTime){ - Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); - if (s == null){ - Debug.LogWarning("Sound: " + name + " not found!"); - yield break; - } + while (s.source.volume < s.volume) { + s.source.volume += Time.deltaTime / fadeTime; + yield return null; + } + s.source.volume = s.volume; + } + /// Use this to fade out a sound and keep playing that muted + /// It has to be in the Sound asset referenced in the AudioManager instance + /// + public void FadeMutedOut(string name, float duration) { + StartCoroutine(FadeMutedOutCoroutine(name, duration)); + } + IEnumerator FadeMutedOutCoroutine(string name, float fadeTime) { + Sounds.List s = Array.Find(soundList.sounds, sound => sound.name == name); + if (s == null) { + Debug.LogWarning("Sound: " + name + " not found!"); + yield break; + } - while (s.source.volume > 0){ - s.source.volume -= Time.deltaTime / fadeTime; - yield return null; - } - s.source.volume = 0; - } - #endregion -} + while (s.source.volume > 0) { + s.source.volume -= Time.deltaTime / fadeTime; + yield return null; + } + s.source.volume = 0; + } + #endregion + } +} \ No newline at end of file diff --git a/Tools/AudioManager/Sounds.cs b/Tools/AudioManager/Sounds.cs index 9f9a5e4..35e2dd0 100644 --- a/Tools/AudioManager/Sounds.cs +++ b/Tools/AudioManager/Sounds.cs @@ -1,50 +1,53 @@ using UnityEngine; using UnityEngine.Audio; -[CreateAssetMenu(fileName = "Sounds", menuName = "Simple Tools/Sounds", order = 11)] -public class Sounds : ScriptableObject{ +namespace SimpleTools.AudioManager { + [CreateAssetMenu(fileName = "Sounds", menuName = "Simple Tools/Sounds", order = 11)] + public class Sounds : ScriptableObject { - [Tooltip("The music mixer.")] - public AudioMixerGroup mainMixer = default; - [Tooltip("The SFX mixer.")] - public AudioMixerGroup sfxMixer = default; + [Tooltip("The music mixer.")] + public AudioMixerGroup mainMixer = default; + [Tooltip("The SFX mixer.")] + public AudioMixerGroup sfxMixer = default; - public List[] sounds; + public List[] sounds; - [System.Serializable] public class List{ - [Tooltip("Name of the sound. Each name has to be different between each other.")] - public string name; + [System.Serializable] + public class List { + [Tooltip("Name of the sound. Each name has to be different between each other.")] + public string name; - public AudioClip clip; + public AudioClip clip; - [System.Serializable] public enum Type { Music, SFX } - [Space] - [Tooltip("Is it part of the music or the SFX?")] public Type type; + [System.Serializable] public enum Type { Music, SFX } + [Space] + [Tooltip("Is it part of the music or the SFX?")] public Type type; - [Space] - [Tooltip("Default volume of the sound."), Range(0f, 1f)] public float volume; - [Tooltip("Variance percentage of the volume"), Range(0f, 1f)] public float volumeVariance; - [Tooltip("Default pitch of the sound."), Range(.1f, 3f)] public float pitch; - [Tooltip("Variance percentage of the pitch"), Range(0f, 1f)] public float pitchVariance; + [Space] + [Tooltip("Default volume of the sound."), Range(0f, 1f)] public float volume; + [Tooltip("Variance percentage of the volume"), Range(0f, 1f)] public float volumeVariance; + [Tooltip("Default pitch of the sound."), Range(.1f, 3f)] public float pitch; + [Tooltip("Variance percentage of the pitch"), Range(0f, 1f)] public float pitchVariance; - public bool loop; + public bool loop; - [HideInInspector] public AudioSource source; + [HideInInspector] public AudioSource source; - float randomVolume; - public float RandomVolume{ - get{ - randomVolume = volume * (1f + Random.Range(-volumeVariance / 2f, volumeVariance / 2f)); - return randomVolume; - } - } + float randomVolume; + public float RandomVolume { + get { + randomVolume = volume * (1f + Random.Range(-volumeVariance / 2f, volumeVariance / 2f)); + return randomVolume; + } + } - float randomPitch; - public float RandomPitch{ - get{ - randomPitch = pitch * (1f + Random.Range(-pitchVariance / 2f, pitchVariance / 2f)); - return randomPitch; - } - } - } -} + float randomPitch; + public float RandomPitch { + get { + randomPitch = pitch * (1f + Random.Range(-pitchVariance / 2f, pitchVariance / 2f)); + return randomPitch; + } + } + } + } +} \ No newline at end of file diff --git a/Tools/Cinemachine/CMCameraTrigger.cs b/Tools/Cinemachine/CMCameraTrigger.cs index b89a5c0..8afd47a 100644 --- a/Tools/Cinemachine/CMCameraTrigger.cs +++ b/Tools/Cinemachine/CMCameraTrigger.cs @@ -1,38 +1,40 @@ using UnityEngine; using Cinemachine; -public class CMCameraTrigger : MonoBehaviour{ +namespace SimpleTools.Cinemachine { + public class CMCameraTrigger : MonoBehaviour { - CinemachineVirtualCamera vcam; + CinemachineVirtualCamera vcam; - void Awake(){ - vcam = GetComponentInChildren(true); - vcam.gameObject.SetActive(false); - } + void Awake() { + vcam = GetComponentInChildren(true); + vcam.gameObject.SetActive(false); + } - #region 3D - void OnTriggerEnter(Collider col){ - if (col.CompareTag("Player")){ - vcam.gameObject.SetActive(true); - } - } - void OnTriggerExit(Collider col){ - if (col.CompareTag("Player")){ - vcam.gameObject.SetActive(true); - } - } - #endregion + #region 3D + void OnTriggerEnter(Collider col) { + if (col.CompareTag("Player")) { + vcam.gameObject.SetActive(true); + } + } + void OnTriggerExit(Collider col) { + if (col.CompareTag("Player")) { + vcam.gameObject.SetActive(true); + } + } + #endregion - #region 2D - void OnTriggerEnter2D(Collider2D col){ - if (col.CompareTag("Player")){ - vcam.gameObject.SetActive(true); - } - } - void OnTriggerExit2D(Collider2D col){ - if (col.CompareTag("Player")){ - vcam.gameObject.SetActive(false); - } - } - #endregion -} + #region 2D + void OnTriggerEnter2D(Collider2D col) { + if (col.CompareTag("Player")) { + vcam.gameObject.SetActive(true); + } + } + void OnTriggerExit2D(Collider2D col) { + if (col.CompareTag("Player")) { + vcam.gameObject.SetActive(false); + } + } + #endregion + } +} \ No newline at end of file diff --git a/Tools/Cinemachine/ScreenShake.cs b/Tools/Cinemachine/ScreenShake.cs index a9d8143..5d4aaa5 100644 --- a/Tools/Cinemachine/ScreenShake.cs +++ b/Tools/Cinemachine/ScreenShake.cs @@ -1,36 +1,38 @@ using Cinemachine; using UnityEngine; -public static class ScreenShake{ +namespace SimpleTools.Cinemachine { + public static class ScreenShake { - static CinemachineVirtualCamera vCam; - static ScreenShakeUpdate shakeUpdate; + static CinemachineVirtualCamera vCam; + static ScreenShakeUpdate shakeUpdate; - class ScreenShakeUpdate : MonoBehaviour { - [HideInInspector] public float shakeTimer; - [HideInInspector] public float shakeTimerTotal; - [HideInInspector] public float startingIntensity; + class ScreenShakeUpdate : MonoBehaviour { + [HideInInspector] public float shakeTimer; + [HideInInspector] public float shakeTimerTotal; + [HideInInspector] public float startingIntensity; - void Update(){ - if (shakeTimer > 0){ - shakeTimer -= Time.deltaTime; - CinemachineBasicMultiChannelPerlin multiChannelPerlin = vCam.GetCinemachineComponent(); - multiChannelPerlin.m_AmplitudeGain = Mathf.Lerp(startingIntensity, 0f, 1 - (shakeTimer / shakeTimerTotal)); - } - } - } + void Update() { + if (shakeTimer > 0) { + shakeTimer -= Time.deltaTime; + CinemachineBasicMultiChannelPerlin multiChannelPerlin = vCam.GetCinemachineComponent(); + multiChannelPerlin.m_AmplitudeGain = Mathf.Lerp(startingIntensity, 0f, 1 - (shakeTimer / shakeTimerTotal)); + } + } + } - /// Shake the camera - /// It needs a cinemachine camera with a noise profile in it. - /// - public static void Shake(float intensity, float time){ - if(vCam == null){ - vCam = Camera.main.GetComponent().ActiveVirtualCamera.VirtualCameraGameObject.GetComponent(); - } - if(shakeUpdate == null){ - shakeUpdate = new GameObject("ShakeUpdate").AddComponent(); - } - shakeUpdate.startingIntensity = intensity; - shakeUpdate.shakeTimer = shakeUpdate.shakeTimerTotal = time; - } -} + /// Shake the camera + /// It needs a cinemachine camera with a noise profile in it. + /// + public static void Shake(float intensity, float time) { + if (vCam == null) { + vCam = Camera.main.GetComponent().ActiveVirtualCamera.VirtualCameraGameObject.GetComponent(); + } + if (shakeUpdate == null) { + shakeUpdate = new GameObject("ShakeUpdate").AddComponent(); + } + shakeUpdate.startingIntensity = intensity; + shakeUpdate.shakeTimer = shakeUpdate.shakeTimerTotal = time; + } + } +} \ No newline at end of file diff --git a/Tools/DialogueSystem/Dialogue.cs b/Tools/DialogueSystem/Dialogue.cs index b7674d0..7b9ce5a 100644 --- a/Tools/DialogueSystem/Dialogue.cs +++ b/Tools/DialogueSystem/Dialogue.cs @@ -1,12 +1,16 @@ using UnityEngine; -[CreateAssetMenu(fileName = "New Character", menuName = "Simple Tools/Character", order = 11)] -public class Dialogue : ScriptableObject{ +namespace SimpleTools.DialogueSystem { + [CreateAssetMenu(fileName = "New Dialogue", menuName = "Simple Tools/Dialogue", order = 11)] + public class Dialogue : ScriptableObject { + public DialogueBox[] sentences; + } - public bool displayName; - public string characterName; - - [Space] - public Sprite characterImage; - [TextArea] public string[] sentences; -} + [System.Serializable] + public class DialogueBox { + public bool displayName; + public string characterName; + public Sprite characterImage; + [TextArea(5, 10)] public string sentence; + } +} \ No newline at end of file diff --git a/Tools/DialogueSystem/DialogueManager.cs b/Tools/DialogueSystem/DialogueManager.cs new file mode 100644 index 0000000..60c4bfb --- /dev/null +++ b/Tools/DialogueSystem/DialogueManager.cs @@ -0,0 +1,112 @@ +using System.Collections.Generic; +using TMPro; +using UnityEngine; +using UnityEngine.UI; + +namespace SimpleTools.DialogueSystem { + public class DialogueManager : MonoBehaviour { + + DialogueVertexAnimator dialogueVertexAnimator; + + Queue sentences; + Queue displayNames; + Queue characterNames; + Queue characterImages; + bool talking; + + public DialogueItems dialogueItems; + + public static DialogueManager instance; + void Awake() { + instance = this; + sentences = new Queue(); + displayNames = new Queue(); + characterNames = new Queue(); + characterImages = new Queue(); + + dialogueVertexAnimator = new DialogueVertexAnimator(dialogueItems.textBox); + } + + public bool Dialogue(Dialogue dialogue) { + return Dialogue(dialogue, ""); + } + + public bool Dialogue(Dialogue dialogue, params string[] sounds) { + if (sounds != null) + dialogueVertexAnimator.SetAudioSourceGroup(sounds); + + if (!talking) { + sentences.Clear(); + if (dialogue.sentences.Length != 0) { + foreach (DialogueBox sentence in dialogue.sentences) { + sentences.Enqueue(sentence.sentence); + displayNames.Enqueue(sentence.displayName); + characterNames.Enqueue(sentence.characterName); + characterImages.Enqueue(sentence.characterImage); + } + } else { + sentences.Enqueue("I am error. No text has been added"); + } + talking = true; + + if (sentences.Count == 0) { + talking = false; + return false; + } + + string sentenceToShow = sentences.Peek(); + bool displayName = displayNames.Peek(); + string characterName = characterNames.Peek(); + Sprite characterImage = characterImages.Peek(); + if (PlayDialogue(sentenceToShow, displayName, characterName, characterImage)) { + sentences.Dequeue(); + displayNames.Dequeue(); + characterNames.Dequeue(); + characterImages.Dequeue(); + } + return true; + } else { + if (sentences.Count == 0) { + talking = false; + return false; + } + + string sentenceToShow = sentences.Peek(); + bool displayName = displayNames.Peek(); + string characterName = characterNames.Peek(); + Sprite characterImage = characterImages.Peek(); + if (PlayDialogue(sentenceToShow, displayName, characterName, characterImage)) { + sentences.Dequeue(); + displayNames.Dequeue(); + characterNames.Dequeue(); + characterImages.Dequeue(); + } + return true; + } + } + + private Coroutine typeRoutine = null; + bool PlayDialogue(string message, bool displayName = false, string characterName = "", Sprite characterImage = null) { + if (dialogueVertexAnimator.IsMessageAnimating()) { + dialogueVertexAnimator.SkipToEndOfCurrentMessage(); + return false; //Next message hasn't been shown because the current one is still animating. + } + this.EnsureCoroutineStopped(ref typeRoutine); + dialogueVertexAnimator.textAnimating = false; + List commands = DialogueUtility.ProcessInputString(message, out string totalTextMessage); + typeRoutine = StartCoroutine(dialogueVertexAnimator.AnimateTextIn(commands, totalTextMessage, null)); + + dialogueItems.characterImage.sprite = characterImage; + dialogueItems.characterName.text = displayName ? characterName : "???"; + return true; //Next message shown successfully + } + } + + [System.Serializable] + public struct DialogueItems { + public Image characterImage; + public TMP_Text characterName; + public TMP_Text textBox; + public Canvas canvas; + } +} \ No newline at end of file diff --git a/Tools/DialogueSystem/DialogueManager.cs.meta b/Tools/DialogueSystem/DialogueManager.cs.meta new file mode 100644 index 0000000..1cc6cbc --- /dev/null +++ b/Tools/DialogueSystem/DialogueManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 23d6a059fd2bc464a9cba3a5ced1724d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tools/DialogueSystem/DialogueUtility.cs b/Tools/DialogueSystem/DialogueUtility.cs new file mode 100644 index 0000000..0483a00 --- /dev/null +++ b/Tools/DialogueSystem/DialogueUtility.cs @@ -0,0 +1,152 @@ +using UnityEngine; +using System.Collections; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System; + +namespace SimpleTools.DialogueSystem { + public class DialogueUtility : MonoBehaviour { + + // grab the remainder of the text until ">" or end of string + const string REMAINDER_REGEX = "(.*?((?=>)|(/|$)))"; + const string PAUSE_REGEX_STRING = "" + REMAINDER_REGEX + ")>"; + static readonly Regex pauseRegex = new Regex(PAUSE_REGEX_STRING); + const string SPEED_REGEX_STRING = "" + REMAINDER_REGEX + ")>"; + static readonly Regex speedRegex = new Regex(SPEED_REGEX_STRING); + const string ANIM_START_REGEX_STRING = "" + REMAINDER_REGEX + ")>"; + static readonly Regex animStartRegex = new Regex(ANIM_START_REGEX_STRING); + const string ANIM_END_REGEX_STRING = ""; + static readonly Regex animEndRegex = new Regex(ANIM_END_REGEX_STRING); + + static readonly Dictionary pauseDictionary = new Dictionary{ + { "tiny", .1f }, + { "short", .25f }, + { "normal", 0.666f }, + { "long", 1f }, + { "read", 2f }, + }; + + public static List ProcessInputString(string message, out string processedMessage) { + List result = new List(); + processedMessage = message; + + processedMessage = HandlePauseTags(processedMessage, result); + processedMessage = HandleSpeedTags(processedMessage, result); + processedMessage = HandleAnimStartTags(processedMessage, result); + processedMessage = HandleAnimEndTags(processedMessage, result); + + return result; + } + + static string HandleAnimEndTags(string processedMessage, List result) { + MatchCollection animEndMatches = animEndRegex.Matches(processedMessage); + foreach (Match match in animEndMatches) { + result.Add(new DialogueCommand { + position = VisibleCharactersUpToIndex(processedMessage, match.Index), + type = DialogueCommandType.AnimEnd, + }); + } + processedMessage = Regex.Replace(processedMessage, ANIM_END_REGEX_STRING, ""); + return processedMessage; + } + + static string HandleAnimStartTags(string processedMessage, List result) { + MatchCollection animStartMatches = animStartRegex.Matches(processedMessage); + foreach (Match match in animStartMatches) { + string stringVal = match.Groups["anim"].Value; + result.Add(new DialogueCommand { + position = VisibleCharactersUpToIndex(processedMessage, match.Index), + type = DialogueCommandType.AnimStart, + textAnimValue = GetTextAnimationType(stringVal) + }); + } + processedMessage = Regex.Replace(processedMessage, ANIM_START_REGEX_STRING, ""); + return processedMessage; + } + + static string HandleSpeedTags(string processedMessage, List result) { + MatchCollection speedMatches = speedRegex.Matches(processedMessage); + foreach (Match match in speedMatches) { + string stringVal = match.Groups["speed"].Value; + if (!float.TryParse(stringVal, out float val)) { + val = 150f; + } + result.Add(new DialogueCommand { + position = VisibleCharactersUpToIndex(processedMessage, match.Index), + type = DialogueCommandType.TextSpeedChange, + floatValue = val + }); + } + processedMessage = Regex.Replace(processedMessage, SPEED_REGEX_STRING, ""); + return processedMessage; + } + + static string HandlePauseTags(string processedMessage, List result) { + MatchCollection pauseMatches = pauseRegex.Matches(processedMessage); + foreach (Match match in pauseMatches) { + string val = match.Groups["pause"].Value; + string pauseName = val; + Debug.Assert(pauseDictionary.ContainsKey(pauseName), "no pause registered for '" + pauseName + "'"); + result.Add(new DialogueCommand { + position = VisibleCharactersUpToIndex(processedMessage, match.Index), + type = DialogueCommandType.Pause, + floatValue = pauseDictionary[pauseName] + }); + } + processedMessage = Regex.Replace(processedMessage, PAUSE_REGEX_STRING, ""); + return processedMessage; + } + + static TextAnimationType GetTextAnimationType(string stringVal) { + TextAnimationType result; + try { + result = (TextAnimationType)Enum.Parse(typeof(TextAnimationType), stringVal, true); + } catch (ArgumentException) { + Debug.LogError("Invalid Text Animation Type: " + stringVal); + result = TextAnimationType.none; + } + return result; + } + + static int VisibleCharactersUpToIndex(string message, int index) { + int result = 0; + bool insideBrackets = false; + for (int i = 0; i < index; i++) { + if (message[i] == '<') { + insideBrackets = true; + } else if (message[i] == '>') { + insideBrackets = false; + result--; + } + if (!insideBrackets) { + result++; + } else if (i + 6 < index && message.Substring(i, 6) == "sprite") { + result++; + } + } + return result; + } + } + public struct DialogueCommand { + public int position; + public DialogueCommandType type; + public float floatValue; + public string stringValue; + public TextAnimationType textAnimValue; + } + + public enum DialogueCommandType { + Pause, + TextSpeedChange, + AnimStart, + AnimEnd + } + + public enum TextAnimationType { + none, + shake, + wave, + wobble, + rainbow, + } +} \ No newline at end of file diff --git a/Tools/DialogueSystem/DialogueUtility.cs.meta b/Tools/DialogueSystem/DialogueUtility.cs.meta new file mode 100644 index 0000000..a98dbdc --- /dev/null +++ b/Tools/DialogueSystem/DialogueUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d4649243ed65dff45b7891eed22eb4c6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tools/DialogueSystem/DialogueVertexAnimator.cs b/Tools/DialogueSystem/DialogueVertexAnimator.cs new file mode 100644 index 0000000..e43ba41 --- /dev/null +++ b/Tools/DialogueSystem/DialogueVertexAnimator.cs @@ -0,0 +1,262 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using TMPro; +using UnityEngine; + +namespace SimpleTools.DialogueSystem { + public class DialogueVertexAnimator { + public bool textAnimating = false; + bool stopAnimating = false; + + readonly TMP_Text textBox; + string[] audioSourceGroup; + public void SetAudioSourceGroup(params string[] _audioSourceGroup) { + audioSourceGroup = _audioSourceGroup; + } + public DialogueVertexAnimator(TMP_Text _textBox) { + textBox = _textBox; + } + + static readonly Color32 clear = new Color32(0, 0, 0, 0); + const float CHAR_ANIM_TIME = 0.07f; + static readonly Vector3 vecZero = Vector3.zero; + public IEnumerator AnimateTextIn(List commands, string processedMessage, Action onFinish) { + textAnimating = true; + float secondsPerCharacter = 1f / 150f; + float timeOfLastCharacter = 0; + + TextAnimInfo[] textAnimInfo = SeparateOutTextAnimInfo(commands); + TMP_TextInfo textInfo = textBox.textInfo; + for (int i = 0; i < textInfo.meshInfo.Length; i++) { + TMP_MeshInfo meshInfer = textInfo.meshInfo[i]; + if (meshInfer.vertices != null) { + for (int j = 0; j < meshInfer.vertices.Length; j++) { + meshInfer.vertices[j] = vecZero; + } + } + } + + textBox.text = processedMessage; + textBox.ForceMeshUpdate(); + + TMP_MeshInfo[] cachedMeshInfo = textInfo.CopyMeshInfoVertexData(); + Color32[][] originalColors = new Color32[textInfo.meshInfo.Length][]; + for (int i = 0; i < originalColors.Length; i++) { + Color32[] theColors = textInfo.meshInfo[i].colors32; + originalColors[i] = new Color32[theColors.Length]; + Array.Copy(theColors, originalColors[i], theColors.Length); + } + int charCount = textInfo.characterCount; + float[] charAnimStartTimes = new float[charCount]; + for (int i = 0; i < charCount; i++) { + charAnimStartTimes[i] = -1; + } + int visableCharacterIndex = 0; + while (true) { + if (stopAnimating) { + for (int i = visableCharacterIndex; i < charCount; i++) { + charAnimStartTimes[i] = Time.unscaledTime; + } + visableCharacterIndex = charCount; + FinishAnimating(onFinish); + } + if (ShouldShowNextCharacter(secondsPerCharacter, timeOfLastCharacter)) { + if (visableCharacterIndex <= charCount) { + ExecuteCommandsForCurrentIndex(commands, visableCharacterIndex, ref secondsPerCharacter, ref timeOfLastCharacter); + if (visableCharacterIndex < charCount && ShouldShowNextCharacter(secondsPerCharacter, timeOfLastCharacter)) { + charAnimStartTimes[visableCharacterIndex] = Time.unscaledTime; + PlayDialogueSound(); + visableCharacterIndex++; + timeOfLastCharacter = Time.unscaledTime; + if (visableCharacterIndex == charCount) { + FinishAnimating(onFinish); + } + } + } + } + for (int j = 0; j < charCount; j++) { + TMP_CharacterInfo charInfo = textInfo.characterInfo[j]; + if (charInfo.isVisible) { + int vertexIndex = charInfo.vertexIndex; + int materialIndex = charInfo.materialReferenceIndex; + Color32[] destinationColors = textInfo.meshInfo[materialIndex].colors32; + Color32 theColor = j < visableCharacterIndex ? originalColors[materialIndex][vertexIndex] : clear; + destinationColors[vertexIndex + 0] = theColor; + destinationColors[vertexIndex + 1] = theColor; + destinationColors[vertexIndex + 2] = theColor; + destinationColors[vertexIndex + 3] = theColor; + + Vector3[] sourceVertices = cachedMeshInfo[materialIndex].vertices; + Vector3[] destinationVertices = textInfo.meshInfo[materialIndex].vertices; + float charSize = 0; + float charAnimStartTime = charAnimStartTimes[j]; + if (charAnimStartTime >= 0) { + float timeSinceAnimStart = Time.unscaledTime - charAnimStartTime; + charSize = Mathf.Min(1, timeSinceAnimStart / CHAR_ANIM_TIME); + } + + Vector3 animPosAdjustment = GetAnimPosAdjustment(textAnimInfo, j, textBox.fontSize, Time.unscaledTime); + Vector3 offset = (sourceVertices[vertexIndex + 0] + sourceVertices[vertexIndex + 2]) / 2; + destinationVertices[vertexIndex + 0] = ((sourceVertices[vertexIndex + 0] - offset) * charSize) + offset + animPosAdjustment; + destinationVertices[vertexIndex + 1] = ((sourceVertices[vertexIndex + 1] - offset) * charSize) + offset + animPosAdjustment; + destinationVertices[vertexIndex + 2] = ((sourceVertices[vertexIndex + 2] - offset) * charSize) + offset + animPosAdjustment; + destinationVertices[vertexIndex + 3] = ((sourceVertices[vertexIndex + 3] - offset) * charSize) + offset + animPosAdjustment; + for (int i = 0; i < 4; i++) { + Vector3 animVertexAdjustment = GetAnimVertexAdjustment(textAnimInfo, j, textBox.fontSize, Time.unscaledTime + i); + destinationVertices[vertexIndex + i] += animVertexAdjustment; + + Color animColorAdjustment = GetAnimColorAdjustment(textAnimInfo, j, Time.unscaledTime + i, destinationVertices[vertexIndex + i]); + if (animColorAdjustment == Color.white) + continue; + destinationColors[vertexIndex + i] += animColorAdjustment; + } + } + } + textBox.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32); + for (int i = 0; i < textInfo.meshInfo.Length; i++) { + TMP_MeshInfo theInfo = textInfo.meshInfo[i]; + theInfo.mesh.vertices = theInfo.vertices; + textBox.UpdateGeometry(theInfo.mesh, i); + } + yield return null; + } + } + + void ExecuteCommandsForCurrentIndex(List commands, int visableCharacterIndex, ref float secondsPerCharacter, ref float timeOfLastCharacter) { + for (int i = 0; i < commands.Count; i++) { + DialogueCommand command = commands[i]; + if (command.position == visableCharacterIndex) { + switch (command.type) { + case DialogueCommandType.Pause: + timeOfLastCharacter = Time.unscaledTime + command.floatValue; + break; + case DialogueCommandType.TextSpeedChange: + secondsPerCharacter = 1f / command.floatValue; + break; + } + commands.RemoveAt(i); + i--; + } + } + } + + void FinishAnimating(Action onFinish) { + textAnimating = false; + stopAnimating = false; + onFinish?.Invoke(); + } + + const float NOISE_MAGNITUDE_ADJUSTMENT = 0.06f; + const float NOISE_FREQUENCY_ADJUSTMENT = 15f; + const float WAVE_MAGNITUDE_ADJUSTMENT = 0.06f; + const float WOBBLE_MAGNITUDE_ADJUSTMENT = 0.5f; + const float RAINBOW_LENGTH_ADJUSTMENT = .001f; + Vector3 GetAnimPosAdjustment(TextAnimInfo[] textAnimInfo, int charIndex, float fontSize, float time) { + float x = 0; + float y = 0; + for (int i = 0; i < textAnimInfo.Length; i++) { + TextAnimInfo info = textAnimInfo[i]; + if (charIndex >= info.startIndex && charIndex < info.endIndex) { + if (info.type == TextAnimationType.shake) { + float scaleAdjust = fontSize * NOISE_MAGNITUDE_ADJUSTMENT; + x += (Mathf.PerlinNoise((charIndex + time) * NOISE_FREQUENCY_ADJUSTMENT, 0) - 0.5f) * scaleAdjust; + y += (Mathf.PerlinNoise((charIndex + time) * NOISE_FREQUENCY_ADJUSTMENT, 1000) - 0.5f) * scaleAdjust; + } else if (info.type == TextAnimationType.wave) { + y += Mathf.Sin((charIndex * 1.5f) + (time * 6)) * fontSize * WAVE_MAGNITUDE_ADJUSTMENT; + } + } + } + return new Vector3(x, y, 0); + } + + Vector3 GetAnimVertexAdjustment(TextAnimInfo[] textAnimInfo, int charIndex, float fontSize, float time) { + float x = 0; + float y = 0; + for (int i = 0; i < textAnimInfo.Length; i++) { + TextAnimInfo info = textAnimInfo[i]; + if (charIndex >= info.startIndex && charIndex < info.endIndex) { + if (info.type == TextAnimationType.wobble) { + float scaleAdjust = fontSize * NOISE_MAGNITUDE_ADJUSTMENT; + x = Mathf.Sin(time * 3.3f) * scaleAdjust * WOBBLE_MAGNITUDE_ADJUSTMENT; + y = Mathf.Cos(time * 2.5f) * scaleAdjust * WOBBLE_MAGNITUDE_ADJUSTMENT; + } + } + } + return new Vector3(x, y, 0); + } + Color GetAnimColorAdjustment(TextAnimInfo[] textAnimInfo, int charIndex, float time, Vector3 destinationVertice) { + Color color = Color.white; + for (int i = 0; i < textAnimInfo.Length; i++) { + TextAnimInfo info = textAnimInfo[i]; + if (charIndex >= info.startIndex && charIndex < info.endIndex) { + if (info.type == TextAnimationType.rainbow) { + color = Color.HSVToRGB(Mathf.Repeat((time + destinationVertice.x * RAINBOW_LENGTH_ADJUSTMENT), 1f), .6f, 1); + } + } + } + return color; + } + + static bool ShouldShowNextCharacter(float secondsPerCharacter, float timeOfLastCharacter) { + return (Time.unscaledTime - timeOfLastCharacter) > secondsPerCharacter; + } + public void SkipToEndOfCurrentMessage() { + if (textAnimating) { + stopAnimating = true; + } + } + public bool IsMessageAnimating() { + return textAnimating; + } + + float timeUntilNextDialogueSound = 0; + float lastDialogueSound = 0; + void PlayDialogueSound() { + if (Time.unscaledTime - lastDialogueSound > timeUntilNextDialogueSound) { + timeUntilNextDialogueSound = UnityEngine.Random.Range(0.02f, 0.08f); + lastDialogueSound = Time.unscaledTime; + if (audioSourceGroup != null) + AudioManager.AudioManager.instance.PlayRandomSound(audioSourceGroup); + } + } + + TextAnimInfo[] SeparateOutTextAnimInfo(List commands) { + List tempResult = new List(); + List animStartCommands = new List(); + List animEndCommands = new List(); + for (int i = 0; i < commands.Count; i++) { + DialogueCommand command = commands[i]; + if (command.type == DialogueCommandType.AnimStart) { + animStartCommands.Add(command); + commands.RemoveAt(i); + i--; + } else if (command.type == DialogueCommandType.AnimEnd) { + animEndCommands.Add(command); + commands.RemoveAt(i); + i--; + } + } + if (animStartCommands.Count != animEndCommands.Count) { + Debug.LogError("Unequal number of start and end animation commands. Start Commands: " + animStartCommands.Count + " End Commands: " + animEndCommands.Count); + } else { + for (int i = 0; i < animStartCommands.Count; i++) { + DialogueCommand startCommand = animStartCommands[i]; + DialogueCommand endCommand = animEndCommands[i]; + tempResult.Add(new TextAnimInfo { + startIndex = startCommand.position, + endIndex = endCommand.position, + type = startCommand.textAnimValue + }); + } + } + return tempResult.ToArray(); + } + } + + public struct TextAnimInfo { + public int startIndex; + public int endIndex; + public TextAnimationType type; + } +} \ No newline at end of file diff --git a/Tools/DialogueSystem/DialogueVertexAnimator.cs.meta b/Tools/DialogueSystem/DialogueVertexAnimator.cs.meta new file mode 100644 index 0000000..8f15ab6 --- /dev/null +++ b/Tools/DialogueSystem/DialogueVertexAnimator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dcef7fafd8716284392e9621424bfa6a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tools/Editor/ToolsEditor.cs b/Tools/Editor/ToolsEditor.cs index acadbd3..c251913 100644 --- a/Tools/Editor/ToolsEditor.cs +++ b/Tools/Editor/ToolsEditor.cs @@ -11,527 +11,538 @@ using UnityEditor.SceneManagement; using UnityEngine.EventSystems; using UnityEditor.Experimental.SceneManagement; using System; +using SimpleTools.AudioManager; +using SimpleTools.DialogueSystem; +using SimpleTools.Cinemachine; +using SimpleTools.SceneManagement; +using SimpleTools.Menu; public class ToolsEditor{ - - [MenuItem("GameObject/Simple Tools/AudioManager", false, 10)] - static void CreateAudioManager(){ - GameObject audioManager = new GameObject("AudioManager"); - audioManager.AddComponent(); - } + + [MenuItem("GameObject/Simple Tools/AudioManager", false, 10)] + static void CreateAudioManager(){ + GameObject audioManager = new GameObject("AudioManager"); + audioManager.AddComponent(); + } - [MenuItem("GameObject/Simple Tools/Dialogue System", false, 10)] - static void CreateDialogueSystem(){ - GameObject dialogueCanvas = new GameObject("DialogueCanvas"); - dialogueCanvas.AddComponent(); - Canvas canvas = dialogueCanvas.AddComponent(); - canvas.renderMode = RenderMode.ScreenSpaceOverlay; - dialogueCanvas.AddComponent(); - dialogueCanvas.AddComponent(); + [MenuItem("GameObject/Simple Tools/Dialogue System", false, 10)] + static void CreateDialogueSystem(){ + GameObject dialogueCanvas = new GameObject("DialogueCanvas"); + dialogueCanvas.AddComponent(); + Canvas canvas = dialogueCanvas.AddComponent(); + canvas.renderMode = RenderMode.ScreenSpaceOverlay; + dialogueCanvas.AddComponent(); + dialogueCanvas.AddComponent(); - GameObject text = new GameObject("TMP_Animated"); - text.transform.SetParent(dialogueCanvas.transform); - text.AddComponent().text = "New Text"; - text.GetComponent().anchoredPosition = Vector2.zero; + GameObject text = new GameObject("DialogueText"); + text.transform.SetParent(dialogueCanvas.transform); + text.AddComponent().text = "Dialogue"; + text.GetComponent().anchoredPosition = Vector2.zero; - GameObject name = new GameObject("NameText"); - name.transform.SetParent(dialogueCanvas.transform); - name.AddComponent().text = "Name"; - name.GetComponent().anchoredPosition = Vector2.up * 50f; + GameObject name = new GameObject("NameText"); + name.transform.SetParent(dialogueCanvas.transform); + name.AddComponent().text = "Name"; + name.GetComponent().anchoredPosition = Vector2.up * 50f; - GameObject image = new GameObject("Image"); - image.transform.SetParent(dialogueCanvas.transform); - image.AddComponent(); - image.GetComponent().anchoredPosition = new Vector2(-150f, 25f); + GameObject image = new GameObject("Image"); + image.transform.SetParent(dialogueCanvas.transform); + image.AddComponent(); + image.GetComponent().anchoredPosition = new Vector2(-150f, 25f); - DialogueSystem dialogueSystem = dialogueCanvas.AddComponent(); - dialogueSystem.nameText = name.GetComponent(); - dialogueSystem.dialogue = text.GetComponent(); - dialogueSystem.faceImage = image.GetComponent(); - dialogueSystem.nameField = name; - } + DialogueManager dialogueManager = dialogueCanvas.AddComponent(); + Debug.Log(dialogueManager.dialogueItems); + dialogueManager.dialogueItems.textBox = text.GetComponent(); + dialogueManager.dialogueItems.characterName = name.GetComponent(); + dialogueManager.dialogueItems.characterImage = image.GetComponent(); + dialogueManager.dialogueItems.canvas = canvas; + //DialogueSystem dialogueSystem = dialogueCanvas.AddComponent(); + //dialogueSystem.nameText = name.GetComponent(); + //dialogueSystem.dialogue = text.GetComponent(); + //dialogueSystem.faceImage = image.GetComponent(); + //dialogueSystem.nameField = name; + } - [MenuItem("GameObject/Simple Tools/Camera Trigger/2D", false, 10)] - static void CreateCameraTrigger2D(){ - GameObject cameraTrigger = new GameObject("CameraTrigger2D"); - cameraTrigger.AddComponent(); - cameraTrigger.AddComponent(); + [MenuItem("GameObject/Simple Tools/Camera Trigger/2D", false, 10)] + static void CreateCameraTrigger2D(){ + GameObject cameraTrigger = new GameObject("CameraTrigger2D"); + cameraTrigger.AddComponent(); + cameraTrigger.AddComponent(); - GameObject vCam = new GameObject("CM vcam1"); - vCam.transform.SetParent(cameraTrigger.transform); - vCam.SetActive(false); - CinemachineVirtualCamera cam = vCam.AddComponent(); - cam.m_Lens.Orthographic = true; - } + GameObject vCam = new GameObject("CM vcam1"); + vCam.transform.SetParent(cameraTrigger.transform); + vCam.SetActive(false); + CinemachineVirtualCamera cam = vCam.AddComponent(); + cam.m_Lens.Orthographic = true; + } - [MenuItem("GameObject/Simple Tools/Camera Trigger/3D", false, 10)] - static void CreateCameraTrigger3D(){ - GameObject cameraTrigger = new GameObject("CameraTrigger3D"); - cameraTrigger.AddComponent(); - cameraTrigger.AddComponent(); + [MenuItem("GameObject/Simple Tools/Camera Trigger/3D", false, 10)] + static void CreateCameraTrigger3D(){ + GameObject cameraTrigger = new GameObject("CameraTrigger3D"); + cameraTrigger.AddComponent(); + cameraTrigger.AddComponent(); - GameObject vCam = new GameObject("CM vcam1"); - vCam.transform.SetParent(cameraTrigger.transform); - vCam.SetActive(false); - CinemachineVirtualCamera cam = vCam.AddComponent(); - cam.m_Lens.FieldOfView = 60f; - } + GameObject vCam = new GameObject("CM vcam1"); + vCam.transform.SetParent(cameraTrigger.transform); + vCam.SetActive(false); + CinemachineVirtualCamera cam = vCam.AddComponent(); + cam.m_Lens.FieldOfView = 60f; + } #if CINEMACHINE_271_OR_NEWER - [MenuItem("GameObject/Simple Tools/ScreenShake Camera/2D", false, 10)] - static void CreateScreenShakeCamera2d(){ - GameObject screenShakeCamera = new GameObject("ScreenShakeCamera"); - CinemachineVirtualCamera vCam = screenShakeCamera.AddComponent(); - vCam.m_Lens.ModeOverride = LensSettings.OverrideModes.Orthographic; + [MenuItem("GameObject/Simple Tools/ScreenShake Camera/2D", false, 10)] + static void CreateScreenShakeCamera2d(){ + GameObject screenShakeCamera = new GameObject("ScreenShakeCamera"); + CinemachineVirtualCamera vCam = screenShakeCamera.AddComponent(); + vCam.m_Lens.ModeOverride = LensSettings.OverrideModes.Orthographic; - CinemachineBasicMultiChannelPerlin shake = vCam.AddCinemachineComponent(); + CinemachineBasicMultiChannelPerlin shake = vCam.AddCinemachineComponent(); - NoiseSettings noise = (NoiseSettings)AssetDatabase.LoadAssetAtPath("Packages/com.unity.cinemachine/Presets/Noise/6D Shake.asset", typeof(NoiseSettings)); + NoiseSettings noise = (NoiseSettings)AssetDatabase.LoadAssetAtPath("Packages/com.unity.cinemachine/Presets/Noise/6D Shake.asset", typeof(NoiseSettings)); - shake.m_NoiseProfile = noise; - shake.m_AmplitudeGain = 0f; - shake.m_FrequencyGain = 1f; - } - [MenuItem("GameObject/Simple Tools/ScreenShake Camera/3D", false, 10)] - static void CreateScreenShakeCamera3d(){ - GameObject screenShakeCamera = new GameObject("ScreenShakeCamera"); - CinemachineVirtualCamera vCam = screenShakeCamera.AddComponent(); - vCam.m_Lens.ModeOverride = LensSettings.OverrideModes.Perspective; + shake.m_NoiseProfile = noise; + shake.m_AmplitudeGain = 0f; + shake.m_FrequencyGain = 1f; + } + [MenuItem("GameObject/Simple Tools/ScreenShake Camera/3D", false, 10)] + static void CreateScreenShakeCamera3d(){ + GameObject screenShakeCamera = new GameObject("ScreenShakeCamera"); + CinemachineVirtualCamera vCam = screenShakeCamera.AddComponent(); + vCam.m_Lens.ModeOverride = LensSettings.OverrideModes.Perspective; - CinemachineBasicMultiChannelPerlin shake = vCam.AddCinemachineComponent(); + CinemachineBasicMultiChannelPerlin shake = vCam.AddCinemachineComponent(); - NoiseSettings noise = (NoiseSettings)AssetDatabase.LoadAssetAtPath("Packages/com.unity.cinemachine/Presets/Noise/6D Shake.asset", typeof(NoiseSettings)); + NoiseSettings noise = (NoiseSettings)AssetDatabase.LoadAssetAtPath("Packages/com.unity.cinemachine/Presets/Noise/6D Shake.asset", typeof(NoiseSettings)); - shake.m_NoiseProfile = noise; - shake.m_AmplitudeGain = 0f; - shake.m_FrequencyGain = 1f; - } + shake.m_NoiseProfile = noise; + shake.m_AmplitudeGain = 0f; + shake.m_FrequencyGain = 1f; + } #else - [MenuItem("GameObject/Simple Tools/ScreenShake Camera", false, 10)] - static void CreateScreenShakeCamera2d(){ - GameObject screenShakeCamera = new GameObject("ScreenShakeCamera"); - CinemachineVirtualCamera vCam = screenShakeCamera.AddComponent(); + [MenuItem("GameObject/Simple Tools/ScreenShake Camera", false, 10)] + static void CreateScreenShakeCamera2d(){ + GameObject screenShakeCamera = new GameObject("ScreenShakeCamera"); + CinemachineVirtualCamera vCam = screenShakeCamera.AddComponent(); - CinemachineBasicMultiChannelPerlin shake = vCam.AddCinemachineComponent(); + CinemachineBasicMultiChannelPerlin shake = vCam.AddCinemachineComponent(); - NoiseSettings noise = (NoiseSettings)AssetDatabase.LoadAssetAtPath("Packages/com.unity.cinemachine/Presets/Noise/6D Shake.asset", typeof(NoiseSettings)); + NoiseSettings noise = (NoiseSettings)AssetDatabase.LoadAssetAtPath("Packages/com.unity.cinemachine/Presets/Noise/6D Shake.asset", typeof(NoiseSettings)); - shake.m_NoiseProfile = noise; - shake.m_AmplitudeGain = 0f; - shake.m_FrequencyGain = 1f; - } + shake.m_NoiseProfile = noise; + shake.m_AmplitudeGain = 0f; + shake.m_FrequencyGain = 1f; + } #endif - [MenuItem("Assets/Create/Simple Tools/Create Loading Scene")] - [MenuItem("Simple Tools/Create Loading Scene")] - static void CreateLoadingScene(){ - EditorSceneManager.SaveOpenScenes(); + [MenuItem("Assets/Create/Simple Tools/Create Loading Scene")] + [MenuItem("Simple Tools/Create Loading Scene")] + static void CreateLoadingScene(){ + EditorSceneManager.SaveOpenScenes(); - Scene loadingScene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects); - loadingScene.name = "Loading"; + Scene loadingScene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects); + loadingScene.name = "Loading"; - GameObject loaderCallback = new GameObject("LoaderCallback"); - loaderCallback.AddComponent(); + GameObject loaderCallback = new GameObject("LoaderCallback"); + loaderCallback.AddComponent(); - GameObject canvasObj = new GameObject("Canvas"); - Canvas canvas = canvasObj.AddComponent(); - canvas.renderMode = RenderMode.ScreenSpaceOverlay; + GameObject canvasObj = new GameObject("Canvas"); + Canvas canvas = canvasObj.AddComponent(); + canvas.renderMode = RenderMode.ScreenSpaceOverlay; - CanvasScaler canvasScaler = canvasObj.AddComponent(); - canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; - canvasScaler.referenceResolution = new Vector2Int(951, 535); - canvasScaler.matchWidthOrHeight = 1f; - - canvasObj.AddComponent(); + CanvasScaler canvasScaler = canvasObj.AddComponent(); + canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; + canvasScaler.referenceResolution = new Vector2Int(951, 535); + canvasScaler.matchWidthOrHeight = 1f; + + canvasObj.AddComponent(); - TextMeshProUGUI loadingText = new GameObject("LoadingText").AddComponent(); - loadingText.transform.SetParent(canvasObj.transform); - RectTransform loadingTextTransform = loadingText.GetComponent(); - loadingTextTransform.anchoredPosition = new Vector2Int(-333, -212); - loadingTextTransform.sizeDelta = new Vector2Int(237, 52); - loadingText.text = "LOADING..."; + TextMeshProUGUI loadingText = new GameObject("LoadingText").AddComponent(); + loadingText.transform.SetParent(canvasObj.transform); + RectTransform loadingTextTransform = loadingText.GetComponent(); + loadingTextTransform.anchoredPosition = new Vector2Int(-333, -212); + loadingTextTransform.sizeDelta = new Vector2Int(237, 52); + loadingText.text = "LOADING..."; - Image bg = new GameObject("bg").AddComponent(); - bg.transform.SetParent(canvasObj.transform); - RectTransform bgTransform = bg.GetComponent(); - bgTransform.anchoredPosition = new Vector2Int(0, -235); - bgTransform.sizeDelta = new Vector2Int(900, 20); - bg.color = new Color(36f / 255f, 36f / 255f, 36f / 255f); + Image bg = new GameObject("bg").AddComponent(); + bg.transform.SetParent(canvasObj.transform); + RectTransform bgTransform = bg.GetComponent(); + bgTransform.anchoredPosition = new Vector2Int(0, -235); + bgTransform.sizeDelta = new Vector2Int(900, 20); + bg.color = new Color(36f / 255f, 36f / 255f, 36f / 255f); - Image progressBar = new GameObject("ProgressBar").AddComponent(); - progressBar.transform.SetParent(bg.transform); - RectTransform progressBarTransform = progressBar.GetComponent(); - progressBarTransform.anchoredPosition = Vector2.zero; - progressBarTransform.sizeDelta = new Vector2Int(900, 20); + Image progressBar = new GameObject("ProgressBar").AddComponent(); + progressBar.transform.SetParent(bg.transform); + RectTransform progressBarTransform = progressBar.GetComponent(); + progressBarTransform.anchoredPosition = Vector2.zero; + progressBarTransform.sizeDelta = new Vector2Int(900, 20); - progressBar.sprite = (Sprite)AssetDatabase.LoadAssetAtPath("Packages/com.geri.simpletools/Simple Tools/Editor/Square.png", typeof(Sprite)); - progressBar.type = Image.Type.Filled; - progressBar.fillMethod = Image.FillMethod.Horizontal; - progressBar.fillOrigin = (int)Image.OriginHorizontal.Left; - progressBar.fillAmount = 1f; - progressBar.gameObject.AddComponent(); - } + progressBar.sprite = (Sprite)AssetDatabase.LoadAssetAtPath("Packages/com.geri.simpletools/Simple Tools/Editor/Square.png", typeof(Sprite)); + progressBar.type = Image.Type.Filled; + progressBar.fillMethod = Image.FillMethod.Horizontal; + progressBar.fillOrigin = (int)Image.OriginHorizontal.Left; + progressBar.fillAmount = 1f; + progressBar.gameObject.AddComponent(); + } #if UNITY_2019_3_OR_NEWER - [MenuItem("Assets/Create/Simple Tools/Create Menu Scene")] - [MenuItem("Simple Tools/Create Menu Scene")] - static void CreateMenuScene(){ - EditorSceneManager.SaveOpenScenes(); + [MenuItem("Assets/Create/Simple Tools/Create Menu Scene")] + [MenuItem("Simple Tools/Create Menu Scene")] + static void CreateMenuScene(){ + EditorSceneManager.SaveOpenScenes(); - Scene menuScene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects); - menuScene.name = "Menu"; + Scene menuScene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects); + menuScene.name = "Menu"; - GameObject canvasObj = new GameObject("Canvas"); - Canvas canvas = canvasObj.AddComponent(); - canvas.renderMode = RenderMode.ScreenSpaceOverlay; + GameObject canvasObj = new GameObject("Canvas"); + Canvas canvas = canvasObj.AddComponent(); + canvas.renderMode = RenderMode.ScreenSpaceOverlay; - CreateEventSystem(false, null); + CreateEventSystem(false, null); - CanvasScaler canvasScaler = canvasObj.AddComponent(); - canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; - canvasScaler.referenceResolution = new Vector2Int(951, 535); - canvasScaler.matchWidthOrHeight = 1f; + CanvasScaler canvasScaler = canvasObj.AddComponent(); + canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; + canvasScaler.referenceResolution = new Vector2Int(951, 535); + canvasScaler.matchWidthOrHeight = 1f; - canvasObj.AddComponent(); + canvasObj.AddComponent(); - GameObject qualityDropdown = TMP_DefaultControls.CreateDropdown(GetStandardResources()); - qualityDropdown.transform.SetParent(canvasObj.transform); - RectTransform qualityRectTransform = qualityDropdown.GetComponent(); - qualityRectTransform.anchoredPosition = Vector2.up * 15f; - qualityDropdown.name = "QualityDropdown"; + GameObject qualityDropdown = TMP_DefaultControls.CreateDropdown(GetStandardResources()); + qualityDropdown.transform.SetParent(canvasObj.transform); + RectTransform qualityRectTransform = qualityDropdown.GetComponent(); + qualityRectTransform.anchoredPosition = Vector2.up * 15f; + qualityDropdown.name = "QualityDropdown"; - GameObject resolutionDropdown = TMP_DefaultControls.CreateDropdown(GetStandardResources()); - resolutionDropdown.transform.SetParent(canvasObj.transform); - RectTransform resolutionRectTransform = resolutionDropdown.GetComponent(); - resolutionRectTransform.anchoredPosition = Vector2.down * 15f; - resolutionDropdown.name = "ResolutionDropdown"; + GameObject resolutionDropdown = TMP_DefaultControls.CreateDropdown(GetStandardResources()); + resolutionDropdown.transform.SetParent(canvasObj.transform); + RectTransform resolutionRectTransform = resolutionDropdown.GetComponent(); + resolutionRectTransform.anchoredPosition = Vector2.down * 15f; + resolutionDropdown.name = "ResolutionDropdown"; - GameObject musicSlider; - using (new FactorySwapToEditor()) - musicSlider = DefaultControls.CreateSlider(GetStandardUIResources()); - musicSlider.transform.SetParent(canvasObj.transform); - RectTransform musicRectTransform = musicSlider.GetComponent(); - musicRectTransform.anchoredPosition = Vector2.down * 40f; - musicSlider.name = "MusicSlider"; + GameObject musicSlider; + using (new FactorySwapToEditor()) + musicSlider = DefaultControls.CreateSlider(GetStandardUIResources()); + musicSlider.transform.SetParent(canvasObj.transform); + RectTransform musicRectTransform = musicSlider.GetComponent(); + musicRectTransform.anchoredPosition = Vector2.down * 40f; + musicSlider.name = "MusicSlider"; - GameObject sfxSlider; - using (new FactorySwapToEditor()) - sfxSlider = DefaultControls.CreateSlider(GetStandardUIResources()); - sfxSlider.transform.SetParent(canvasObj.transform); - RectTransform sfxRectTransform = sfxSlider.GetComponent(); - sfxRectTransform.anchoredPosition = Vector2.down * 60; - sfxSlider.name = "MusicSlider"; + GameObject sfxSlider; + using (new FactorySwapToEditor()) + sfxSlider = DefaultControls.CreateSlider(GetStandardUIResources()); + sfxSlider.transform.SetParent(canvasObj.transform); + RectTransform sfxRectTransform = sfxSlider.GetComponent(); + sfxRectTransform.anchoredPosition = Vector2.down * 60; + sfxSlider.name = "MusicSlider"; - GameObject playButton = TMP_DefaultControls.CreateButton(GetStandardResources()); - playButton.transform.SetParent(canvasObj.transform); - TMP_Text playTextComponent = playButton.GetComponentInChildren(); - playTextComponent.fontSize = 24; - playTextComponent.text = "PLAY"; - RectTransform playRectTransform = playButton.GetComponent(); - playRectTransform.anchoredPosition = Vector2.up * 45f; - playButton.name = "PlayButton"; + GameObject playButton = TMP_DefaultControls.CreateButton(GetStandardResources()); + playButton.transform.SetParent(canvasObj.transform); + TMP_Text playTextComponent = playButton.GetComponentInChildren(); + playTextComponent.fontSize = 24; + playTextComponent.text = "PLAY"; + RectTransform playRectTransform = playButton.GetComponent(); + playRectTransform.anchoredPosition = Vector2.up * 45f; + playButton.name = "PlayButton"; - GameObject quitButton = TMP_DefaultControls.CreateButton(GetStandardResources()); - quitButton.transform.SetParent(canvasObj.transform); - TMP_Text quitTextComponent = quitButton.GetComponentInChildren(); - quitTextComponent.fontSize = 24; - quitTextComponent.text = "QUIT"; - RectTransform quitRectTransform = quitButton.GetComponent(); - quitRectTransform.anchoredPosition = Vector2.down * 85f; - quitButton.name = "QuitButton"; + GameObject quitButton = TMP_DefaultControls.CreateButton(GetStandardResources()); + quitButton.transform.SetParent(canvasObj.transform); + TMP_Text quitTextComponent = quitButton.GetComponentInChildren(); + quitTextComponent.fontSize = 24; + quitTextComponent.text = "QUIT"; + RectTransform quitRectTransform = quitButton.GetComponent(); + quitRectTransform.anchoredPosition = Vector2.down * 85f; + quitButton.name = "QuitButton"; - MenuController menuController = canvasObj.AddComponent(); - Slider sliderMusic = menuController.musicSlider = musicSlider.GetComponent(); - Slider sliderSfx = menuController.sfxSlider = sfxSlider.GetComponent(); - TMP_Dropdown dropdownQuality = menuController.qualityDropdown = qualityDropdown.GetComponent(); - TMP_Dropdown dropdownResolution = menuController.resolutionDropdown = resolutionDropdown.GetComponent(); + MenuController menuController = canvasObj.AddComponent(); + Slider sliderMusic = menuController.musicSlider = musicSlider.GetComponent(); + Slider sliderSfx = menuController.sfxSlider = sfxSlider.GetComponent(); + TMP_Dropdown dropdownQuality = menuController.qualityDropdown = qualityDropdown.GetComponent(); + TMP_Dropdown dropdownResolution = menuController.resolutionDropdown = resolutionDropdown.GetComponent(); - sliderMusic.onValueChanged.AddListener(menuController.SetMusicVolume); - sliderSfx.onValueChanged.AddListener(menuController.SetSfxVolume); - dropdownQuality.onValueChanged.AddListener(menuController.SetQuality); - dropdownResolution.onValueChanged.AddListener(menuController.SetResolution); + sliderMusic.onValueChanged.AddListener(menuController.SetMusicVolume); + sliderSfx.onValueChanged.AddListener(menuController.SetSfxVolume); + dropdownQuality.onValueChanged.AddListener(menuController.SetQuality); + dropdownResolution.onValueChanged.AddListener(menuController.SetResolution); - playButton.GetComponent