From 25f469c26a60b1b69131364662b3a3dd1455c256 Mon Sep 17 00:00:00 2001 From: minenice55 Date: Mon, 3 Apr 2023 12:40:41 -0400 Subject: [PATCH] add proper way of getting clip length (#385) add code doc to Jukebox --- .../Games/CheerReaders/CheerReaders.cs | 3 +- Assets/Scripts/Util/Jukebox.cs | 89 +++++++++++++++++-- 2 files changed, 84 insertions(+), 8 deletions(-) diff --git a/Assets/Scripts/Games/CheerReaders/CheerReaders.cs b/Assets/Scripts/Games/CheerReaders/CheerReaders.cs index 6fb8e446..b0b082e1 100644 --- a/Assets/Scripts/Games/CheerReaders/CheerReaders.cs +++ b/Assets/Scripts/Games/CheerReaders/CheerReaders.cs @@ -1401,7 +1401,8 @@ namespace HeavenStudio.Games void SuccessHoldSpin() { player.StartSpinBook(); - SpinningLoop = Jukebox.PlayOneShotScheduledGame("cheerReaders/bookSpinLoop", Jukebox.PlayOneShotGame("cheerReaders/bookSpin").clip.length, 1, 1, true); + Jukebox.PlayOneShotGame("cheerReaders/bookSpin"); + SpinningLoop = Jukebox.PlayOneShotScheduledGame("cheerReaders/bookSpinLoop", Jukebox.GetClipLengthGame("cheerReaders/bookSpin"), 1, 1, true); } void JustReleaseSpin(PlayerActionEvent caller, float state) diff --git a/Assets/Scripts/Util/Jukebox.cs b/Assets/Scripts/Util/Jukebox.cs index 7a77a4d2..ae70aba3 100644 --- a/Assets/Scripts/Util/Jukebox.cs +++ b/Assets/Scripts/Util/Jukebox.cs @@ -17,7 +17,7 @@ namespace HeavenStudio.Util } /// - /// This is me just idiot-proofing. + /// Ensures that the jukebox and one-shot audio source exist. /// public static void BasicCheck() { @@ -45,12 +45,9 @@ namespace HeavenStudio.Util return null; } - public static void SetVolume(float volume) - { - BasicCheck(); - FindJukebox().GetComponent().volume = volume; - } - + /// + /// Stops all currently playing sounds. + /// public static void KillOneShots() { if (oneShotAudioSource != null) @@ -59,6 +56,63 @@ namespace HeavenStudio.Util } } + /// + /// Gets the length of an audio clip + /// + public static double GetClipLength(string name, float pitch = 1f, string game = null) + { + AudioClip clip = null; + if (game != null) + { + string soundName = name.Split('/')[2]; + var inf = GameManager.instance.GetGameInfo(game); + //first try the game's common assetbundle + // Debug.Log("Jukebox loading sound " + soundName + " from common"); + clip = inf.GetCommonAssetBundle()?.LoadAsset(soundName); + //then the localized one + if (clip == null) + { + // Debug.Log("Jukebox loading sound " + soundName + " from locale"); + clip = inf.GetLocalizedAssetBundle()?.LoadAsset(soundName); + } + } + + //can't load from assetbundle, load from resources + if (clip == null) + { + // Debug.Log("Jukebox loading sound " + name + " from resources"); + clip = Resources.Load($"Sfx/{name}"); + } + + if (clip == null) + { + Debug.LogError($"Could not load clip {name}"); + return double.NaN; + } + return clip.length / pitch; + } + + /// + /// Gets the length of an audio clip + /// Audio clip is fetched from minigame resources + /// + public static double GetClipLengthGame(string name, float pitch = 1f) + { + string gameName = name.Split('/')[0]; + var inf = GameManager.instance.GetGameInfo(gameName); + if (inf != null) + { + return GetClipLength($"games/{name}", pitch, inf.usesAssetBundle ? gameName : null); + } + + return double.NaN; + } + + /// + /// Fires a one-shot sound. + /// Unpitched, non-scheduled, non-looping sounds are played using a global One-Shot audio source that doesn't create a Sound object. + /// Looped sounds return their created Sound object so they can be canceled after creation. + /// public static Sound PlayOneShot(string name, float beat = -1, float pitch = 1f, float volume = 1f, bool looping = false, string game = null) { AudioClip clip = null; @@ -119,6 +173,9 @@ namespace HeavenStudio.Util } } + /// + /// Schedules a sound to be played at a specific time in seconds. + /// public static Sound PlayOneShotScheduled(string name, double targetTime, float pitch = 1f, float volume = 1f, bool looping = false, string game = null) { GameObject oneShot = new GameObject("oneShotScheduled"); @@ -162,6 +219,11 @@ namespace HeavenStudio.Util return snd; } + /// + /// Fires a one-shot sound located in minigame resources. + /// Unpitched, non-scheduled, non-looping sounds are played using a global One-Shot audio source that doesn't create a Sound object. + /// Looped sounds return their created Sound object so they can be canceled after creation. + /// public static Sound PlayOneShotGame(string name, float beat = -1, float pitch = 1f, float volume = 1f, bool looping = false, bool forcePlay = false) { string gameName = name.Split('/')[0]; @@ -174,6 +236,10 @@ namespace HeavenStudio.Util return null; } + /// + /// Schedules a sound to be played at a specific time in seconds. + /// Audio clip is fetched from minigame resources + /// public static Sound PlayOneShotScheduledGame(string name, double targetTime, float pitch = 1f, float volume = 1f, bool looping = false, bool forcePlay = false) { string gameName = name.Split('/')[0]; @@ -186,6 +252,9 @@ namespace HeavenStudio.Util return null; } + /// + /// Stops a looping Sound + /// public static void KillLoop(Sound source, float fadeTime) { // Safeguard against previously-destroyed sounds. @@ -195,6 +264,9 @@ namespace HeavenStudio.Util source.KillLoop(fadeTime); } + /// + /// Gets a pitch multiplier from semitones. + /// public static float GetPitchFromSemiTones(int semiTones, bool pitchToMusic) { if (pitchToMusic) @@ -207,6 +279,9 @@ namespace HeavenStudio.Util } } + /// + /// Gets a pitch multiplier from cents. + /// public static float GetPitchFromCents(int cents, bool pitchToMusic) { if (pitchToMusic)