using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Audio; using Sirenix.OdinInspector; #if UNITY_EDITOR using Unity.EditorCoroutines.Editor; #endif namespace KairoEngine.SFX { public enum SFXClipType { Single, RandomList, Steps } public enum SFXSpace { Stereo, GameWorld, Mix } [HideMonoScript] [CreateAssetMenu(menuName = "KairoEngine/SFX/Clip", fileName = "SFXClip", order = 1)] public class SFXClip : ScriptableObject { [Space, Title("Audio Clip")] [PropertyOrder(0)] public SFXClipType sfxType = SFXClipType.Single; [PropertyOrder(2), Required, ShowIf("@sfxType == SFXClipType.Single")] public AudioClip clip; [PropertyOrder(3), Required, ShowIf("@sfxType == SFXClipType.RandomList")] public List clips; [PropertyOrder(4), Required, ShowIf("@sfxType == SFXClipType.Steps"), ShowInInspector] public List clipSteps; #region PlayButtons #if UNITY_EDITOR private bool stopSteps = false; [PropertyOrder(5), Button("Stop"), HorizontalGroup("Controls")] public void StopEditor() { if(sfxType == SFXClipType.Single && clip != null) SFXUtil.StopClip(clip); else if(sfxType == SFXClipType.RandomList && clips != null) { if(clips.Count > 0) { foreach (var clip in clips) SFXUtil.StopClip(clip); } } else if(sfxType == SFXClipType.Steps && clipSteps != null) { stopSteps = true; foreach (var step in clipSteps) step.clip.StopEditor(); } SFXUtil.StopAllClips(); } [PropertyOrder(6), Button("Play"), HorizontalGroup("Controls")] public void PlayEditor() { if(sfxType == SFXClipType.Single && clip != null) SFXUtil.PlayClip(clip); else if(sfxType == SFXClipType.RandomList && clips != null) { if(clips.Count > 0) { SFXUtil.PlayClip(clips[Random.Range(0, clips.Count)]); } } else if(sfxType == SFXClipType.Steps && clipSteps != null) { stopSteps = false; foreach (var step in clipSteps) { EditorCoroutineUtility.StartCoroutineOwnerless(PlayStep(step.startTime, step.clip)); } } } public IEnumerator PlayStep(float waitTime, SFXClip clip) { bool hasPlayed = false; var waitFor = new EditorWaitForSeconds(waitTime); while (hasPlayed == false) { yield return waitFor; if(stopSteps == false) { hasPlayed = true; if(clip.sfxType == SFXClipType.Single) SFXUtil.PlayClip(clip.clip); else if (clip.sfxType == SFXClipType.RandomList) { if(clip.clips != null) { if(clip.clips.Count > 0) { SFXUtil.PlayClip(clip.clips[Random.Range(0, clip.clips.Count)]); } } } } } } #endif #endregion [Title("Clip Settings")] [PropertyOrder(7), ShowIf("@sfxType == SFXClipType.Single || sfxType == SFXClipType.RandomList")] public bool loop = false; [PropertyOrder(8), Range(0f, 1f)] public float volume = 1f; [PropertyOrder(9), Range(0f, 0.2f)] public float volumeVariation = 0.05f; [PropertyOrder(10), Range(0f, 2f)] public float pitch = 1f; [PropertyOrder(11), Range(0f, 0.2f)] public float pitchVariation = 0.05f; [PropertyOrder(12), HorizontalGroup("Trim"), LabelText("@trim ? \"Trim Start/Stop\" : \"Trim\"")] public bool trim = false; [PropertyOrder(13), HorizontalGroup("Trim", Width = 0.272f), HideLabel, SuffixLabel("seconds", true), ShowIf("@trim")] public float trimStartDuration = 0; [PropertyOrder(14), HorizontalGroup("Trim", Width = 0.272f), HideLabel, SuffixLabel("seconds", true), ShowIf("@trim")] public float trimEndDuration = 0; [PropertyOrder(15), HorizontalGroup("FadeIn"), LabelText("@fadeIn ? \"Fade In Duration\" : \"Fade In\"")] public bool fadeIn = false; [PropertyOrder(16), HorizontalGroup("FadeIn", Width = 0.55f), HideLabel, SuffixLabel("seconds", true), ShowIf("@fadeIn")] public float fadeInDuration = 1f; [PropertyOrder(17), HorizontalGroup("FadeOut"), LabelText("@fadeOut ? \"Fade Out Duration\" : \"Fade Out\"")] public bool fadeOut = false; [PropertyOrder(18), HorizontalGroup("FadeOut", Width = 0.55f), HideLabel, SuffixLabel("seconds", true), ShowIf("@fadeOut")] public float fadeOutDuration = 1f; [PropertyOrder(19)] public SFXSpace soundSpace = SFXSpace.GameWorld; [PropertyOrder(20), Range(-1f, 1f), ShowIf("@soundSpace == SFXSpace.Stereo || soundSpace == SFXSpace.Mix")] public float pan = 0f; [PropertyOrder(21), Range(0f, 0.2f), ShowIf("@soundSpace == SFXSpace.Stereo || soundSpace == SFXSpace.Mix")] public float panVariation = 0.05f; [PropertyOrder(22), Range(0f, 1f), ShowIf("@soundSpace == SFXSpace.Mix")] public float spatialBlend = 0f; [PropertyOrder(23),Range(0f, 0.2f), ShowIf("@soundSpace == SFXSpace.Mix")] public float spatialBlendVariation = 0.05f; [PropertyOrder(24), ShowIf("@soundSpace == SFXSpace.GameWorld || soundSpace == SFXSpace.Mix"), LabelText("Distance")] [HorizontalGroup("Distance"), SuffixLabel("min", true)] public float minDistance = 3f; [PropertyOrder(25), ShowIf("@soundSpace == SFXSpace.GameWorld || soundSpace == SFXSpace.Mix"), HideLabel()] [HorizontalGroup("Distance", Width = 0.3f), SuffixLabel("max", true)] public float maxDistance = 100f; [PropertyOrder(26), Required, HideIf("@sfxType == SFXClipType.Steps")] public AudioMixerGroup audioMixerChannel; [PropertyOrder(27)] public bool removeOnSceneChange = false; [Title("World Settings")] [PropertyOrder(28)] public bool sensorDetection = true; [PropertyOrder(29), ShowIf(@"sensorDetection"), Range(0f, 100f)] public float soundRadius = 2f; } }