From 1df7a33ab065d1f27ec6d0f53ff1c1d5a2f2efca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerard=20Gasc=C3=B3n?= <52170489+GerardGascon@users.noreply.github.com> Date: Thu, 22 Sep 2022 13:43:53 +0200 Subject: [PATCH] Add files via upload --- SimpleTools/LICENSE.md | 19 + SimpleTools/LICENSE.md.meta | 7 + SimpleTools/README.md | 145 +++++ SimpleTools/README.md.meta | 7 + SimpleTools/Tools.meta | 8 + SimpleTools/Tools/AudioManager.meta | 8 + .../Tools/AudioManager/AudioManager.cs | 271 +++++++++ .../Tools/AudioManager/AudioManager.cs.meta | 11 + .../Tools/AudioManager/AudioManager.png | Bin 0 -> 1644 bytes .../Tools/AudioManager/AudioManager.png.meta | 96 +++ SimpleTools/Tools/AudioManager/Sounds.cs | 53 ++ SimpleTools/Tools/AudioManager/Sounds.cs.meta | 11 + SimpleTools/Tools/Cinemachine.meta | 8 + .../Tools/Cinemachine/CMCameraTrigger.cs | 40 ++ .../Tools/Cinemachine/CMCameraTrigger.cs.meta | 11 + SimpleTools/Tools/Cinemachine/ScreenShake.cs | 38 ++ .../Tools/Cinemachine/ScreenShake.cs.meta | 11 + SimpleTools/Tools/DialogueSystem.meta | 8 + SimpleTools/Tools/DialogueSystem/Dialogue.cs | 16 + .../Tools/DialogueSystem/Dialogue.cs.meta | 11 + SimpleTools/Tools/DialogueSystem/Dialogue.png | Bin 0 -> 2405 bytes .../Tools/DialogueSystem/Dialogue.png.meta | 96 +++ .../Tools/DialogueSystem/DialogueManager.cs | 111 ++++ .../DialogueSystem/DialogueManager.cs.meta | 11 + .../Tools/DialogueSystem/DialogueUtility.cs | 170 ++++++ .../DialogueSystem/DialogueUtility.cs.meta | 11 + .../DialogueSystem/DialogueVertexAnimator.cs | 265 +++++++++ .../DialogueVertexAnimator.cs.meta | 11 + SimpleTools/Tools/Editor.meta | 8 + SimpleTools/Tools/Editor/Square.png | Bin 0 -> 78 bytes SimpleTools/Tools/Editor/Square.png.meta | 104 ++++ SimpleTools/Tools/Editor/ToolsEditor.cs | 548 ++++++++++++++++++ SimpleTools/Tools/Editor/ToolsEditor.cs.meta | 11 + SimpleTools/Tools/Menu.meta | 8 + SimpleTools/Tools/Menu/MenuController.cs | 110 ++++ SimpleTools/Tools/Menu/MenuController.cs.meta | 11 + SimpleTools/Tools/MonobehaviourExtensions.cs | 12 + .../Tools/MonobehaviourExtensions.cs.meta | 11 + SimpleTools/Tools/ObjectPooler.meta | 8 + .../Tools/ObjectPooler/IPooledObject.cs | 5 + .../Tools/ObjectPooler/IPooledObject.cs.meta | 11 + .../Tools/ObjectPooler/ObjectPooler.png | Bin 0 -> 4554 bytes .../Tools/ObjectPooler/ObjectPooler.png.meta | 96 +++ SimpleTools/Tools/ObjectPooler/Pool.cs | 20 + SimpleTools/Tools/ObjectPooler/Pool.cs.meta | 11 + SimpleTools/Tools/ObjectPooler/Pooler.cs | 371 ++++++++++++ SimpleTools/Tools/ObjectPooler/Pooler.cs.meta | 11 + SimpleTools/Tools/SceneManager.meta | 8 + SimpleTools/Tools/SceneManager/Loader.cs | 71 +++ SimpleTools/Tools/SceneManager/Loader.cs.meta | 11 + .../Tools/SceneManager/LoaderCallback.cs | 16 + .../Tools/SceneManager/LoaderCallback.cs.meta | 11 + .../Tools/SceneManager/LoadingProgressBar.cs | 19 + .../SceneManager/LoadingProgressBar.cs.meta | 11 + SimpleTools/Tools/Timer.meta | 8 + SimpleTools/Tools/Timer/Timer.cs | 99 ++++ SimpleTools/Tools/Timer/Timer.cs.meta | 11 + SimpleTools/Tools/Timer/TimerType.cs | 7 + SimpleTools/Tools/Timer/TimerType.cs.meta | 11 + SimpleTools/Tools/Timer/TimerUpdate.cs | 6 + SimpleTools/Tools/Timer/TimerUpdate.cs.meta | 11 + SimpleTools/Tools/Timer/TimerUtility.cs | 36 ++ SimpleTools/Tools/Timer/TimerUtility.cs.meta | 11 + .../Tools/geri.simpletools.editor.asmdef | 24 + .../Tools/geri.simpletools.editor.asmdef.meta | 7 + SimpleTools/package.json | 23 + SimpleTools/package.json.meta | 7 + manifest.json | 40 ++ packages-lock.json | 325 +++++++++++ 69 files changed, 3583 insertions(+) create mode 100644 SimpleTools/LICENSE.md create mode 100644 SimpleTools/LICENSE.md.meta create mode 100644 SimpleTools/README.md create mode 100644 SimpleTools/README.md.meta create mode 100644 SimpleTools/Tools.meta create mode 100644 SimpleTools/Tools/AudioManager.meta create mode 100644 SimpleTools/Tools/AudioManager/AudioManager.cs create mode 100644 SimpleTools/Tools/AudioManager/AudioManager.cs.meta create mode 100644 SimpleTools/Tools/AudioManager/AudioManager.png create mode 100644 SimpleTools/Tools/AudioManager/AudioManager.png.meta create mode 100644 SimpleTools/Tools/AudioManager/Sounds.cs create mode 100644 SimpleTools/Tools/AudioManager/Sounds.cs.meta create mode 100644 SimpleTools/Tools/Cinemachine.meta create mode 100644 SimpleTools/Tools/Cinemachine/CMCameraTrigger.cs create mode 100644 SimpleTools/Tools/Cinemachine/CMCameraTrigger.cs.meta create mode 100644 SimpleTools/Tools/Cinemachine/ScreenShake.cs create mode 100644 SimpleTools/Tools/Cinemachine/ScreenShake.cs.meta create mode 100644 SimpleTools/Tools/DialogueSystem.meta create mode 100644 SimpleTools/Tools/DialogueSystem/Dialogue.cs create mode 100644 SimpleTools/Tools/DialogueSystem/Dialogue.cs.meta create mode 100644 SimpleTools/Tools/DialogueSystem/Dialogue.png create mode 100644 SimpleTools/Tools/DialogueSystem/Dialogue.png.meta create mode 100644 SimpleTools/Tools/DialogueSystem/DialogueManager.cs create mode 100644 SimpleTools/Tools/DialogueSystem/DialogueManager.cs.meta create mode 100644 SimpleTools/Tools/DialogueSystem/DialogueUtility.cs create mode 100644 SimpleTools/Tools/DialogueSystem/DialogueUtility.cs.meta create mode 100644 SimpleTools/Tools/DialogueSystem/DialogueVertexAnimator.cs create mode 100644 SimpleTools/Tools/DialogueSystem/DialogueVertexAnimator.cs.meta create mode 100644 SimpleTools/Tools/Editor.meta create mode 100644 SimpleTools/Tools/Editor/Square.png create mode 100644 SimpleTools/Tools/Editor/Square.png.meta create mode 100644 SimpleTools/Tools/Editor/ToolsEditor.cs create mode 100644 SimpleTools/Tools/Editor/ToolsEditor.cs.meta create mode 100644 SimpleTools/Tools/Menu.meta create mode 100644 SimpleTools/Tools/Menu/MenuController.cs create mode 100644 SimpleTools/Tools/Menu/MenuController.cs.meta create mode 100644 SimpleTools/Tools/MonobehaviourExtensions.cs create mode 100644 SimpleTools/Tools/MonobehaviourExtensions.cs.meta create mode 100644 SimpleTools/Tools/ObjectPooler.meta create mode 100644 SimpleTools/Tools/ObjectPooler/IPooledObject.cs create mode 100644 SimpleTools/Tools/ObjectPooler/IPooledObject.cs.meta create mode 100644 SimpleTools/Tools/ObjectPooler/ObjectPooler.png create mode 100644 SimpleTools/Tools/ObjectPooler/ObjectPooler.png.meta create mode 100644 SimpleTools/Tools/ObjectPooler/Pool.cs create mode 100644 SimpleTools/Tools/ObjectPooler/Pool.cs.meta create mode 100644 SimpleTools/Tools/ObjectPooler/Pooler.cs create mode 100644 SimpleTools/Tools/ObjectPooler/Pooler.cs.meta create mode 100644 SimpleTools/Tools/SceneManager.meta create mode 100644 SimpleTools/Tools/SceneManager/Loader.cs create mode 100644 SimpleTools/Tools/SceneManager/Loader.cs.meta create mode 100644 SimpleTools/Tools/SceneManager/LoaderCallback.cs create mode 100644 SimpleTools/Tools/SceneManager/LoaderCallback.cs.meta create mode 100644 SimpleTools/Tools/SceneManager/LoadingProgressBar.cs create mode 100644 SimpleTools/Tools/SceneManager/LoadingProgressBar.cs.meta create mode 100644 SimpleTools/Tools/Timer.meta create mode 100644 SimpleTools/Tools/Timer/Timer.cs create mode 100644 SimpleTools/Tools/Timer/Timer.cs.meta create mode 100644 SimpleTools/Tools/Timer/TimerType.cs create mode 100644 SimpleTools/Tools/Timer/TimerType.cs.meta create mode 100644 SimpleTools/Tools/Timer/TimerUpdate.cs create mode 100644 SimpleTools/Tools/Timer/TimerUpdate.cs.meta create mode 100644 SimpleTools/Tools/Timer/TimerUtility.cs create mode 100644 SimpleTools/Tools/Timer/TimerUtility.cs.meta create mode 100644 SimpleTools/Tools/geri.simpletools.editor.asmdef create mode 100644 SimpleTools/Tools/geri.simpletools.editor.asmdef.meta create mode 100644 SimpleTools/package.json create mode 100644 SimpleTools/package.json.meta create mode 100644 manifest.json create mode 100644 packages-lock.json diff --git a/SimpleTools/LICENSE.md b/SimpleTools/LICENSE.md new file mode 100644 index 0000000..58c3550 --- /dev/null +++ b/SimpleTools/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (c) 2021 Geri + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/SimpleTools/LICENSE.md.meta b/SimpleTools/LICENSE.md.meta new file mode 100644 index 0000000..de5ec90 --- /dev/null +++ b/SimpleTools/LICENSE.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 535f36a1918d4d2479031f3ca2725323 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SimpleTools/README.md b/SimpleTools/README.md new file mode 100644 index 0000000..b9678df --- /dev/null +++ b/SimpleTools/README.md @@ -0,0 +1,145 @@ +# Simple Tools + +This package contains simple tools to use in your project. + +This package will be updated once I find another useful tool or someone suggest me one. + +## Features + +- **AudioManager** with Play, Pause and most of the other basic things, as well as some effects like FadeIn or FadeOut. +- Some Cinemachine tools for making a **camera trigger** and an easy way for creating a **screen shake camera.** +- Basic **dialogue system** that works with TextMeshPro. +- 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. + +All of that comes with some editor menu items for creating all of that as fast as possible. + +## How to install + +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) + +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)" + +### Manual Installation + +Download latest package from the Release section Import SimpleTools.unitypackage to your Unity Project + +## Usage + +### 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) +AudioManager.instance.PlayWithIntro("Intro", "Loop"); //Plays the intro and then the loop + +AudioManager.instance.Pause("Name"); //Pauses the sound +AudioManager.instance.UnPause("Name"); //Unpauses the sound + +AudioManager.instance.Stop("Name"); //Stops the sound +AudioManager.instance.StopAll(); //Stops all the sounds that are being played + +AudioManager.instance.GetSource("Name"); //Gets the AudioSource with that name + +AudioManager.instance.FadeIn("Name", 1f); //Fade In the source with a specific duration +AudioManager.instance.FadeOut("Name", 1f); //Fade Out the source with a specific duration + +AudioManager.instance.PlayMuted("Name"); //Play a sound muted +AudioManager.instance.FadeMutedIn("Name", 1f); //Fade In a muted sound with a specific duration +AudioManager.instance.FadeMutedOut("Name", 1f); //Fade Out a sound without stopping it +``` + +### ObjectPooler + +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; +Pooler.CreatePools(pools); //Create multiple pools +Pooler.Destroy(gameObject); //Destroys a GameObject and returns it into the pool scene + +Pooler.SpawnFromPool("Name", Vector3.zero); //Spawns an object into a specific position +Pooler.SpawnFromPool("Name", Vector3.zero, Quaternion.identity); //Spawn into a specific position and rotation +Pooler.SpawnFromPool("Name", Vector3.zero, transform); //Spawn into a specific position and parent +Pooler.SpawnFromPool("Name", Vector3.zero, Quaternion.identity, transform); //Spawn into a specific position, rotation and parent +Pooler.SpawnFromPool("Name", Vector3.zero, transform, true); //Spawn into a specific position, parent and instantiate in worldSpace or not +Pooler.SpawnFromPool("Name", Vector3.zero, Quaternion.identity, transform, true); //Spawn into a specific position, rotation, parent and instantiate in worldSpace or not +``` + +### Dialogue System + +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: + +```html + --> 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 +``` + +### ScreenShake + +```csharp +using SimpleTools.Cinemachine; + +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. + +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/SimpleTools/README.md.meta b/SimpleTools/README.md.meta new file mode 100644 index 0000000..3c5c492 --- /dev/null +++ b/SimpleTools/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ee23fd1b6b87e954f836c97747d4c083 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SimpleTools/Tools.meta b/SimpleTools/Tools.meta new file mode 100644 index 0000000..b32c30e --- /dev/null +++ b/SimpleTools/Tools.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 78a1b199ab0716542b34cc9a3dd3a9df +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SimpleTools/Tools/AudioManager.meta b/SimpleTools/Tools/AudioManager.meta new file mode 100644 index 0000000..f12a26c --- /dev/null +++ b/SimpleTools/Tools/AudioManager.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1d98cf7b5d008ba4a832612b94195e04 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SimpleTools/Tools/AudioManager/AudioManager.cs b/SimpleTools/Tools/AudioManager/AudioManager.cs new file mode 100644 index 0000000..7ce5230 --- /dev/null +++ b/SimpleTools/Tools/AudioManager/AudioManager.cs @@ -0,0 +1,271 @@ +using System.Collections; +using UnityEngine; +using System; + +namespace SimpleTools.AudioManager { + public class AudioManager : MonoBehaviour { + + public static AudioManager instance; + + [SerializeField] Sounds soundList = default; + + 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; + } + + 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; + } + + s.source.clip = s.clip; + + 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(); + + 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); + + if (audioSource && audioSource.isPlaying) { + float startVolume = audioSource.volume; + + while (audioSource.volume > 0) { + audioSource.volume -= startVolume * Time.deltaTime / fadeTime; + yield return null; + } + + 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; + } + + 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 + } +} \ No newline at end of file diff --git a/SimpleTools/Tools/AudioManager/AudioManager.cs.meta b/SimpleTools/Tools/AudioManager/AudioManager.cs.meta new file mode 100644 index 0000000..4a77e93 --- /dev/null +++ b/SimpleTools/Tools/AudioManager/AudioManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7d2879f3876727040b4f0cc799ec7ada +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SimpleTools/Tools/AudioManager/AudioManager.png b/SimpleTools/Tools/AudioManager/AudioManager.png new file mode 100644 index 0000000000000000000000000000000000000000..712262f738675eb46063dce66b4855e7118a2d82 GIT binary patch literal 1644 zcmb`I`9IqS1INF)5XLJNM+l0DRD&WBY2yfr#?=Tb)tG2{sM1BWiKmors*GB-R`>lx|un>!_nE4Ueg`?rU*2iyGzW{)gv>&*%O6yxxDnCx;pAr>$wM2>^gLAeXDu>V$=W{XCAr*c`UP&Se zXSc_9rvB-#DBapx7OwPFk}z2@n7YB*q2&c)dIPt(3g@Tw+Aspv2I+&n%P}1b>P$&F zkVII)58wVI+LX>`&CA>O!q~_@Xk+)iiKn{R7L+R>{_Vld8*ClhBBD2?1X$hYz)|1* znz-uDYvl(%-xmdTf+S+vES+P-d&~;-w21=W{IYpa_+d;Z@Po-wp1??Fdm~wA$27Zt-tfgZ6$s{S)CpKBTb>EBeK#x zCUw!k=)*=178kMazPN!4y?FDLeKmhYEf096WOvD>uu*MC$o7M=>w;tY%cE8jo7 zc)@z_z`yd30H@fdHm`m|z$5N(9Q3ydEhF~}??t0`fuv?J88SIwgJz&XAyz!HAMMoz zBRS)mtU}gGab2i`Y56u2+7^~1$lyfi!K)`dAemgKULKN3wWd#$0RPV+OGvEmEp!Rg zJ@B`>+L84$EwW!)6o@vRkG_KG2zTw)7rJ7k3TF5G4vG-&kD(Tx1Wq{+=g5ch%BSYy#vJLLf;Y%zXP8 zI9n)xy6}Sy`0IAd>|n?fv5hp5@}}6m3|g-cBz*J<1!Dw_gMOi427jTpVnB~`e~{Lq z6RY{U;;73^?j1k{XTr#c`R+T#J3$muc^Nc5%$7!Z%RiTmWLD;7A?`H$hJwydF0x>M zoqmyM5UaTwV_zwg5*R*jyvc|N-CD%N@uE;J8Ig<~5l5uiK8hTuwE=0Hx%#~~pFbWu z=6tRlHQ2~bi>*?p%*f0WAXVM*^m;oHrcG=oHDK)Ag4u74bOesB8(Ms&RlTPs4>eZC zpzU~SK!#60uSm=S)X=a6tJr|Tm1UsCx{}PZaGD;5O>xZ<>zqnZm!Tn-H+hFY|@K` z%=+cws1k)CPcp6CrFzL-V7TeC5-Mxdp<`)2QG;jtz=D1y>GY>bC2$EJaGjRb>ITaK z!ilNGcJ<}kZr`vM%f77Yy>BYH6MxCOOW5NWsrn+Wu>AKQbDf6$FOT|sCn5hOs{B!A zadw5sr>gY?O_@JQ-6(X<4&pn%wIz%!X*WeSn(qbLeJ^ChV0`0%bimlTKhuMxo%i`g O0ESQS;YKgc)&BuiP1UIY literal 0 HcmV?d00001 diff --git a/SimpleTools/Tools/AudioManager/AudioManager.png.meta b/SimpleTools/Tools/AudioManager/AudioManager.png.meta new file mode 100644 index 0000000..61ce9f6 --- /dev/null +++ b/SimpleTools/Tools/AudioManager/AudioManager.png.meta @@ -0,0 +1,96 @@ +fileFormatVersion: 2 +guid: af0857324620d1d4b8b6bf41b6cdecfc +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/SimpleTools/Tools/AudioManager/Sounds.cs b/SimpleTools/Tools/AudioManager/Sounds.cs new file mode 100644 index 0000000..35e2dd0 --- /dev/null +++ b/SimpleTools/Tools/AudioManager/Sounds.cs @@ -0,0 +1,53 @@ +using UnityEngine; +using UnityEngine.Audio; + +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; + + 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; + + public AudioClip clip; + + [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; + + public bool loop; + + [HideInInspector] public AudioSource source; + + 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; + } + } + } + } +} \ No newline at end of file diff --git a/SimpleTools/Tools/AudioManager/Sounds.cs.meta b/SimpleTools/Tools/AudioManager/Sounds.cs.meta new file mode 100644 index 0000000..a22e5ea --- /dev/null +++ b/SimpleTools/Tools/AudioManager/Sounds.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6ded47588579f3047b1c3cd72cd87044 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: af0857324620d1d4b8b6bf41b6cdecfc, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SimpleTools/Tools/Cinemachine.meta b/SimpleTools/Tools/Cinemachine.meta new file mode 100644 index 0000000..608d7cd --- /dev/null +++ b/SimpleTools/Tools/Cinemachine.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5a2ff5ceb779d824d811d139fa608262 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SimpleTools/Tools/Cinemachine/CMCameraTrigger.cs b/SimpleTools/Tools/Cinemachine/CMCameraTrigger.cs new file mode 100644 index 0000000..8afd47a --- /dev/null +++ b/SimpleTools/Tools/Cinemachine/CMCameraTrigger.cs @@ -0,0 +1,40 @@ +using UnityEngine; +using Cinemachine; + +namespace SimpleTools.Cinemachine { + public class CMCameraTrigger : MonoBehaviour { + + CinemachineVirtualCamera vcam; + + 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 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/SimpleTools/Tools/Cinemachine/CMCameraTrigger.cs.meta b/SimpleTools/Tools/Cinemachine/CMCameraTrigger.cs.meta new file mode 100644 index 0000000..7d3bb42 --- /dev/null +++ b/SimpleTools/Tools/Cinemachine/CMCameraTrigger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 368758c1440a4cb4c867e140e8934c09 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SimpleTools/Tools/Cinemachine/ScreenShake.cs b/SimpleTools/Tools/Cinemachine/ScreenShake.cs new file mode 100644 index 0000000..5d4aaa5 --- /dev/null +++ b/SimpleTools/Tools/Cinemachine/ScreenShake.cs @@ -0,0 +1,38 @@ +using Cinemachine; +using UnityEngine; + +namespace SimpleTools.Cinemachine { + public static class ScreenShake { + + static CinemachineVirtualCamera vCam; + static ScreenShakeUpdate shakeUpdate; + + 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)); + } + } + } + + /// 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/SimpleTools/Tools/Cinemachine/ScreenShake.cs.meta b/SimpleTools/Tools/Cinemachine/ScreenShake.cs.meta new file mode 100644 index 0000000..048e505 --- /dev/null +++ b/SimpleTools/Tools/Cinemachine/ScreenShake.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 181034c7ad5ece241a2737ab35d47c5c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SimpleTools/Tools/DialogueSystem.meta b/SimpleTools/Tools/DialogueSystem.meta new file mode 100644 index 0000000..b94d838 --- /dev/null +++ b/SimpleTools/Tools/DialogueSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 645cca644899cc74882ea9bc1d9c5aa9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SimpleTools/Tools/DialogueSystem/Dialogue.cs b/SimpleTools/Tools/DialogueSystem/Dialogue.cs new file mode 100644 index 0000000..7b9ce5a --- /dev/null +++ b/SimpleTools/Tools/DialogueSystem/Dialogue.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +namespace SimpleTools.DialogueSystem { + [CreateAssetMenu(fileName = "New Dialogue", menuName = "Simple Tools/Dialogue", order = 11)] + public class Dialogue : ScriptableObject { + public DialogueBox[] 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/SimpleTools/Tools/DialogueSystem/Dialogue.cs.meta b/SimpleTools/Tools/DialogueSystem/Dialogue.cs.meta new file mode 100644 index 0000000..63ccf99 --- /dev/null +++ b/SimpleTools/Tools/DialogueSystem/Dialogue.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd553cd05b84d614b998afe62e37c17c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 4dfc626116fd10c4f972c17720d957ac, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SimpleTools/Tools/DialogueSystem/Dialogue.png b/SimpleTools/Tools/DialogueSystem/Dialogue.png new file mode 100644 index 0000000000000000000000000000000000000000..3bff2d35af56bc93cbb250520d3bfcca02168d49 GIT binary patch literal 2405 zcmV-r37YnaP) z3G5w39mhZa2Noz6S_qd?ZUj=LfK)l<2uFbcLQ-f6(JDwnF~NcXBPJ*z9EA!RLO4R9 zB>@x&P*TX>fZT`LDzOJpX@GE4u7Xf1El17N-y@I5|Lx4a-I<-){e6;`9&dKvZ+5=B zJM)|Q{RTx*6h%=KrFjgTzv$CEl^z8g0_+8R3)mdk5cmqPT0V7TKn zn4fZeT?H@>m;xLRY~bIlq<9**9+;7$@h!{un*cL`zXFrB@rT4b4Q~LR1&)o-zD%+N zU@Eg1_(24Arohg?-N3ae8Qn_&Ka6`U?bod zOSvc1AJCIQXCZ)edEv&h7F_%;NhoULzxb11x2(1C|A{CuPpG*uFck zacuQ70vKZ{b7LS|Qs-r0Zblu<5P8?w>e#Y$PL>0I4`@&7JZ!OlbZqrA0{Cji_pbsU z2ec=3UbomkBDVUqEY6?h0d1)RA6n`#EVeqfEUS3d3TR6muwAduVymNVL5NawQ~(V} z1<-I*01Zb4&~Q`$4Mzpga8v*dM+MMuQ~(V}1yC-w;MnMbXH@{@@`mMXZ^mY@>oV}z z*;>NY$4EHah>no%P^<*LZTYP;B+|NQ*w}!4%!=&yfmdX)?%ceqv{M$qX28k71mL?7 z*yF-}^6|yLfd_y;0{6Q7MvAY1^<+8r5(&CUrSU_sx!e@9C8Ymo+i#{OfbkNt{tICJ z2<(ZOaUuj0m9%azJ5v(CxxoFvmJ!&J5|e;M63O%>QW1c8^ zI8z?^N->55Pjx5#h+P1C#vE9gAREdk;d5di2Ik3EFi+z2o|WNHT~pR|Vmf!*$c=I& zu&Ki_##b@5od_gm0i5L+QEPG({0ew5fK4$oT+;ho=#Z%6x02cH{a9ZCMwq{GD0elm zw>JJ7OcKkBB>e0(hw^4rWlignD~)K0Ot3^OAz4b!sK~yUSs<^36&4#!;?IGWrIC9& z5Il2|<@7H}mJ(%XOdset%e671frE_z{+m(g>lIw!VGbedQv%tNGJgUdv)F$`%Q8hd zYAEM{XU159D3^*yP_bhhLho(_@VuqaguoZtmU(MVAUo=S30MClqaIru0X%7`=+wX$ z!j?s2NgzAwz%t8-U}Vc7x6McyGls&pSmM1#HDPhy$vDF>Gv0ntHa{4bQSiqyya>)|^{`Z9I!47Ma=%ZoXV$*T82+Y@*`aG&Kw#(T7tq(1c-=Wc7Lyw0mzW%W>9 zFbvXJDWb1vXS$1I@Ri3=8)V_qso zbt}y{k!AsZsQ3a`<<0a(sZZZd0W6Zo%cVJv-%UQfc)1S&{3mC5r2yS`?X;5f0>0J9 zG24~+`-+93ItZr6e^W&lZX$4AMZeuhdi4;0BqM{6Oq3pb*;CZts9D37nr=30L5N8q z|ETzr$Cmk{L(pz~ADkzXT6ORP40JE)DvE7I(8JQn`-#lG`w)W9#y9-VKT> z2;qCuQ8d$xZ6exHGXtEbrq!4jl8N7K*&44 zZrQ|26?7E|B5aLs8~^8B6nUJ)1=OK$v5pLr^N@AD20{zK<<2iVF5sD*d4)!xU)${$yK2QkmsGB70YJWsRVnP!lsryOUptCAa93nvE}=t3fj{o4zY|H zUh*w~etP>R&D*;f-)}5YOp2YeEG6do6hOa2y-yq_J9MF^orwth5I`ADo_icRgU8Co2)gaf7dcS&3b6T8*5nT=`{I@9;XBu% zjLBd0oc0OUFdCRHuTNW!#g%2HitTjTlxEH@Nbh8secAu0A80BKvh2- z+IQi7mX2)}yGl$(ce1BXC7asUWY?6#bIcP=5fKy?K)Zquc=GKZ?U2Q+%?=J3#;W2K z>5%mkEp4K*ep;g44@#ERH59!=#>lYk(BgIt$zlmUNuAM>+b7E_*NZY&NWI$aM=2_R zJAm&LJco^0va~F9w(L^`Wn~0eDzA!_o&Q->0P}(61<&Ea^qS-b?pFjw`G?60Dt)6b zkkSxphNQClX9TtsA+!j75A4w^SypOe=(!T2evV^K{8$Mg0+TFyf7x@XC#gD7E|XkB zlYzS&oJKL?Lj-2TbQQ3d3=1E(9gyf zgRP3xKn38JP$K9X6@Y)D7J&*N3`IoXHLyhm5RQICK*yh6PyvJ`uLw*U|9yR0r~(Mj zLYY8w5y5zyC$A_ffNEHfLj+z?0aQm6B2WQTOXVU^0aQ<=B2WRuL1iLP0mMTkB2WRu zMOy?Pg|bQo5FZP~SrkMBDu6f%CIS^eyaW+}3LtL0i$DbsKVC(k0!RaIB2WROgBKB~ z0Mep#5vTytqwOqeXFe^I0aXQ%Ci5lI7YWhto4N#sG!c^m_ZW$SQWQl|6h%=KM}YqU X65^Z_x-SEH00000NkvXXu0mjf!ZT!a literal 0 HcmV?d00001 diff --git a/SimpleTools/Tools/DialogueSystem/Dialogue.png.meta b/SimpleTools/Tools/DialogueSystem/Dialogue.png.meta new file mode 100644 index 0000000..4991597 --- /dev/null +++ b/SimpleTools/Tools/DialogueSystem/Dialogue.png.meta @@ -0,0 +1,96 @@ +fileFormatVersion: 2 +guid: 4dfc626116fd10c4f972c17720d957ac +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/SimpleTools/Tools/DialogueSystem/DialogueManager.cs b/SimpleTools/Tools/DialogueSystem/DialogueManager.cs new file mode 100644 index 0000000..4b025a9 --- /dev/null +++ b/SimpleTools/Tools/DialogueSystem/DialogueManager.cs @@ -0,0 +1,111 @@ +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, string.Empty); + } + + public bool Dialogue(Dialogue dialogue, params string[] sounds) { + 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/SimpleTools/Tools/DialogueSystem/DialogueManager.cs.meta b/SimpleTools/Tools/DialogueSystem/DialogueManager.cs.meta new file mode 100644 index 0000000..1cc6cbc --- /dev/null +++ b/SimpleTools/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/SimpleTools/Tools/DialogueSystem/DialogueUtility.cs b/SimpleTools/Tools/DialogueSystem/DialogueUtility.cs new file mode 100644 index 0000000..98a67c3 --- /dev/null +++ b/SimpleTools/Tools/DialogueSystem/DialogueUtility.cs @@ -0,0 +1,170 @@ +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 SOUND_REGEX_STRING = "" + REMAINDER_REGEX + ")>"; + static readonly Regex soundRegex = new Regex(SOUND_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 = HandleSoundTags(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 string HandleSoundTags(string processedMessage, List result) { + MatchCollection soundMatches = soundRegex.Matches(processedMessage); + foreach (Match match in soundMatches) { + string val = match.Groups["sound"].Value; + string soundName = val; + result.Add(new DialogueCommand { + position = VisibleCharactersUpToIndex(processedMessage, match.Index), + type = DialogueCommandType.Sound, + stringValue = soundName + }); + } + processedMessage = Regex.Replace(processedMessage, SOUND_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, + Sound + } + + public enum TextAnimationType { + none, + shake, + wave, + wobble, + rainbow, + } +} \ No newline at end of file diff --git a/SimpleTools/Tools/DialogueSystem/DialogueUtility.cs.meta b/SimpleTools/Tools/DialogueSystem/DialogueUtility.cs.meta new file mode 100644 index 0000000..a98dbdc --- /dev/null +++ b/SimpleTools/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/SimpleTools/Tools/DialogueSystem/DialogueVertexAnimator.cs b/SimpleTools/Tools/DialogueSystem/DialogueVertexAnimator.cs new file mode 100644 index 0000000..24eb6e4 --- /dev/null +++ b/SimpleTools/Tools/DialogueSystem/DialogueVertexAnimator.cs @@ -0,0 +1,265 @@ +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; + case DialogueCommandType.Sound: + AudioManager.AudioManager.instance.PlayOneShot(command.stringValue); + 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[0] != string.Empty) + 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/SimpleTools/Tools/DialogueSystem/DialogueVertexAnimator.cs.meta b/SimpleTools/Tools/DialogueSystem/DialogueVertexAnimator.cs.meta new file mode 100644 index 0000000..8f15ab6 --- /dev/null +++ b/SimpleTools/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/SimpleTools/Tools/Editor.meta b/SimpleTools/Tools/Editor.meta new file mode 100644 index 0000000..550a16f --- /dev/null +++ b/SimpleTools/Tools/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 53d517df853ee5d44b788e900f897c54 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/SimpleTools/Tools/Editor/Square.png b/SimpleTools/Tools/Editor/Square.png new file mode 100644 index 0000000000000000000000000000000000000000..8eb1b1ecc13b6e1d2375151866134cd7a040340c GIT binary patch literal 78 zcmeAS@N?(olHy`uVBq!ia0vp^EFjFm1|(O0oL2{=L_J*`LpWrU|M0W$cr!i aF)*;jval%k(); + } + + [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("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 image = new GameObject("Image"); + image.transform.SetParent(dialogueCanvas.transform); + image.AddComponent(); + image.GetComponent().anchoredPosition = new Vector2(-150f, 25f); + + 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(); + + 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(); + + 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; + + CinemachineBasicMultiChannelPerlin shake = vCam.AddCinemachineComponent(); + + 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; + + CinemachineBasicMultiChannelPerlin shake = vCam.AddCinemachineComponent(); + + 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; + } +#else + [MenuItem("GameObject/Simple Tools/ScreenShake Camera", false, 10)] + static void CreateScreenShakeCamera2d(){ + GameObject screenShakeCamera = new GameObject("ScreenShakeCamera"); + CinemachineVirtualCamera vCam = screenShakeCamera.AddComponent(); + + CinemachineBasicMultiChannelPerlin shake = vCam.AddCinemachineComponent(); + + 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; + } +#endif + + [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"; + + GameObject loaderCallback = new GameObject("LoaderCallback"); + loaderCallback.AddComponent(); + + 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(); + + 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 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(); + } + +#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(); + + Scene menuScene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects); + menuScene.name = "Menu"; + + GameObject canvasObj = new GameObject("Canvas"); + Canvas canvas = canvasObj.AddComponent(); + canvas.renderMode = RenderMode.ScreenSpaceOverlay; + + CreateEventSystem(false, null); + + CanvasScaler canvasScaler = canvasObj.AddComponent(); + canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; + canvasScaler.referenceResolution = new Vector2Int(951, 535); + canvasScaler.matchWidthOrHeight = 1f; + + 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 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 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 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(); + + sliderMusic.onValueChanged.AddListener(menuController.SetMusicVolume); + sliderSfx.onValueChanged.AddListener(menuController.SetSfxVolume); + dropdownQuality.onValueChanged.AddListener(menuController.SetQuality); + dropdownResolution.onValueChanged.AddListener(menuController.SetResolution); + + playButton.GetComponent