diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index dac3fdd6..ac338b95 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -224,7 +224,7 @@ namespace RhythmHeavenMania SetCurrentEventToClosest(beat); } - for (int i = 0; i < SoundObjects.Count; i++) Destroy(SoundObjects[i].gameObject); + KillAllSounds(); } public void Pause() @@ -237,6 +237,13 @@ namespace RhythmHeavenMania Conductor.instance.Stop(beat); SetCurrentEventToClosest(beat); onBeatChanged?.Invoke(beat); + KillAllSounds(); + } + + public void KillAllSounds() + { + for (int i = 0; i < SoundObjects.Count; i++) + Destroy(SoundObjects[i].gameObject); } #endregion diff --git a/Assets/Scripts/Games/BuiltToScaleDS/BuiltToScaleDS.cs b/Assets/Scripts/Games/BuiltToScaleDS/BuiltToScaleDS.cs index ec410e10..c69dd1c6 100644 --- a/Assets/Scripts/Games/BuiltToScaleDS/BuiltToScaleDS.cs +++ b/Assets/Scripts/Games/BuiltToScaleDS/BuiltToScaleDS.cs @@ -184,5 +184,16 @@ namespace RhythmHeavenMania.Games.BuiltToScaleDS shooterAnim.Play("Shoot", 0, 0); elevatorAnim.Play("MakeRod", 0, 0); } + + public void PlayPiano(float beat, float length, int semiTones) + { + var pianoPitch = Mathf.Pow(2f, (1f / 12f) * semiTones); + var pianoSource = Jukebox.PlayOneShotGame("builtToScaleDS/Piano", -1, pianoPitch, true); + + BeatAction.New(gameObject, new List() + { + new BeatAction.Action(beat + length, delegate { Jukebox.KillLoop(pianoSource, 0.1f); }) + }); + } } } \ No newline at end of file diff --git a/Assets/Scripts/Minigames.cs b/Assets/Scripts/Minigames.cs index 1ecc5be1..f500d665 100644 --- a/Assets/Scripts/Minigames.cs +++ b/Assets/Scripts/Minigames.cs @@ -352,9 +352,13 @@ namespace RhythmHeavenMania new Param("type2", RotateMode.Fast, "Rotation Mode", "The rotation mode to use") } ), }), - new Minigame("builtToScaleDS", "Built To Scale (DS) \n[WIP don't use]", "00BB00", true, false, new List() + new Minigame("builtToScaleDS", "Built To Scale (DS)", "00BB00", true, false, new List() { - new GameAction("spawn blocks", delegate { }, 1f, true) + new GameAction("spawn blocks", delegate { }, 1f, true), + new GameAction("play piano", delegate { BuiltToScaleDS.instance.PlayPiano(eventCaller.currentEntity.beat, eventCaller.currentEntity.length, eventCaller.currentEntity.type); }, 1f, true, new List() + { + new Param("type", new EntityTypes.Integer(-24, 24, 0), "Semitones", "The number of semitones up or down this note should be pitched") + } ), }), new Minigame("tapTrial", "Tap Trial \n[WIP don't use]", "93ffb3", false, false, new List() { diff --git a/Assets/Scripts/Util/Jukebox.cs b/Assets/Scripts/Util/Jukebox.cs index 079039fd..3dca5ccc 100644 --- a/Assets/Scripts/Util/Jukebox.cs +++ b/Assets/Scripts/Util/Jukebox.cs @@ -40,7 +40,7 @@ namespace RhythmHeavenMania.Util FindJukebox().GetComponent().volume = volume; } - public static AudioSource PlayOneShot(string name, float beat = -1) + public static AudioSource PlayOneShot(string name, float beat = -1, float pitch = 1f, bool looping = false) { GameObject oneShot = new GameObject("oneShot"); @@ -52,6 +52,8 @@ namespace RhythmHeavenMania.Util AudioClip clip = Resources.Load($"Sfx/{name}"); snd.clip = clip; snd.beat = beat; + snd.pitch = pitch; + snd.looping = looping; // snd.pitch = (clip.length / Conductor.instance.secPerBeat); GameManager.instance.SoundObjects.Add(oneShot); @@ -59,7 +61,7 @@ namespace RhythmHeavenMania.Util return audioSource; } - public static AudioSource PlayOneShotScheduled(string name, double targetTime) + public static AudioSource PlayOneShotScheduled(string name, double targetTime, float pitch = 1f, bool looping = false) { GameObject oneShot = new GameObject("oneShotScheduled"); @@ -71,6 +73,8 @@ namespace RhythmHeavenMania.Util var clip = Resources.Load($"Sfx/{name}"); audioSource.clip = clip; snd.clip = clip; + snd.pitch = pitch; + snd.looping = looping; snd.scheduled = true; snd.scheduledTime = targetTime; @@ -81,25 +85,30 @@ namespace RhythmHeavenMania.Util return audioSource; } - public static AudioSource PlayOneShotGame(string name, float beat = -1) + public static AudioSource PlayOneShotGame(string name, float beat = -1, float pitch = 1f, bool looping = false) { if (GameManager.instance.currentGame == name.Split('/')[0]) { - return PlayOneShot($"games/{name}", beat); + return PlayOneShot($"games/{name}", beat, pitch, looping); } return null; } - public static AudioSource PlayOneShotScheduledGame(string name, double targetTime) + public static AudioSource PlayOneShotScheduledGame(string name, double targetTime, float pitch = 1f, bool looping = false) { if (GameManager.instance.currentGame == name.Split('/')[0]) { - return PlayOneShotScheduled($"games/{name}", targetTime); + return PlayOneShotScheduled($"games/{name}", targetTime, pitch, looping); } return null; } + + public static void KillLoop(AudioSource source, float fadeTime) + { + source.GetComponent().KillLoop(fadeTime); + } } } \ No newline at end of file diff --git a/Assets/Scripts/Util/Sound.cs b/Assets/Scripts/Util/Sound.cs index b4b13799..66f51a14 100644 --- a/Assets/Scripts/Util/Sound.cs +++ b/Assets/Scripts/Util/Sound.cs @@ -13,6 +13,8 @@ namespace RhythmHeavenMania.Util public bool scheduled; public double scheduledTime; + public bool looping; + private AudioSource audioSource; private int pauseTimes = 0; @@ -29,6 +31,7 @@ namespace RhythmHeavenMania.Util audioSource = GetComponent(); audioSource.clip = clip; audioSource.pitch = pitch; + audioSource.loop = looping; if (beat == -1 && !scheduled) { @@ -43,33 +46,59 @@ namespace RhythmHeavenMania.Util startTime = Conductor.instance.songPosition; - if (!scheduled) + if (!scheduled && !looping) StartCoroutine(NotRelyOnBeatSound()); } private void Update() { - if (scheduled) + if (playIndex < 1) { - if (AudioSettings.dspTime > scheduledTime && playIndex < 1) + if (scheduled) { - StartCoroutine(NotRelyOnBeatSound()); - playIndex++; + if (AudioSettings.dspTime > scheduledTime) + { + StartCoroutine(NotRelyOnBeatSound()); + playIndex++; + } } - } - else if (!playInstant) - { - if (Conductor.instance.songPositionInBeats > beat && playIndex < 1) + else if (!playInstant) { - audioSource.PlayScheduled(Time.time); - playIndex++; + if (Conductor.instance.songPositionInBeats > beat) + { + audioSource.PlayScheduled(Time.time); + playIndex++; + } } } } IEnumerator NotRelyOnBeatSound() { - yield return new WaitForSeconds(clip.length); + if (!looping) // Looping sounds are destroyed manually. + { + yield return new WaitForSeconds(clip.length); + Destroy(this.gameObject); + } + } + + public void KillLoop(float fadeTime) + { + StartCoroutine(FadeLoop(fadeTime)); + } + + float loopFadeTimer = 0f; + IEnumerator FadeLoop(float fadeTime) + { + float startingVol = audioSource.volume; + + while (loopFadeTimer < fadeTime) + { + loopFadeTimer += Time.deltaTime; + audioSource.volume = Mathf.Max((1f - (loopFadeTimer / fadeTime)) * startingVol, 0f); + yield return null; + } + Destroy(this.gameObject); } }