So I used this tutorial: https://www.youtube.com/watch?v=tLyj02T51Oc, to create an AudioManager that can be easily called from other scripts, and can fade sound effects. One thing I do not know how to do is how to play a sound when let's say the player is running. I only have a function that plays an sfx, but all the SFX have looped equal to false, and I know that a running noise will need the SFX to loop. How can I add a function to this script so that running noises can be correctly implemented? The script:
using System.Collections.Generic;
using UnityEngine;
public class AudioManager : MonoBehaviour
{
#region Instances
private static AudioManager _instance = null;
public static AudioManager Instance
{
get
{
if (_instance == null) //if instance doesn't exist, find an AudioManager
{
_instance = new AudioManager();
}
return _instance;
}
private set
{
_instance = value;
}
}
#endregion
#region Fields
//the audio source can only play one looping sound at a time
private AudioSource musicSource;
private AudioSource musicSource2; //purpose of having 2 musicSources is that we can use them to achieve effects like CrossFade
private AudioSource sfxSource;
private bool firstMusicSourceIsPlaying;
#endregion
private void Awake()
{
if(_instance == null)
{
//Set this instance as the instance reference
_instance = this;
}
else if(_instance != this)
{
//If the instance reference has already been set, and this is not the instance reference, destroy the game object
Destroy(gameObject);
}
//Make sure we don't destroy this instance
DontDestroyOnLoad(_instance);
//Create audio sources, and make them as references
musicSource = this.gameObject.AddComponent<AudioSource>();
musicSource2 = this.gameObject.AddComponent<AudioSource>();
sfxSource = this.gameObject.AddComponent<AudioSource>();
//loop musicSource
musicSource.loop = true;
musicSource2.loop = true;
}
//plays the music
public void PlayMusic(AudioClip musicClip)
{
//Determine which source is active (if the boolean is true, play musicSource, else play musicSource2)
AudioSource activeSource = (firstMusicSourceIsPlaying) ? musicSource : musicSource2;
activeSource.clip = musicClip;
activeSource.volume = 1; //volume is between 0 and 1
activeSource.Play();
}
//fade out the first music, fade in the second (new) music
public void PlayMusicWithFade(AudioClip newClip, float musicVolume, float transitionTime = 1.0f)
{
//Determine which source is active (if the boolean is true, play musicSource, else play musicSource2)
AudioSource activeSource = (firstMusicSourceIsPlaying) ? musicSource : musicSource2;
StartCoroutine(UpdateMusicWithFade(activeSource, newClip, transitionTime, musicVolume));
}
public void StopMusicWithFade(float musicVolume, float transitionTime = 1.0f)
{
//Determine which source is active (if the boolean is true, play musicSource, else play musicSource2)
AudioSource activeSource = (firstMusicSourceIsPlaying) ? musicSource : musicSource2;
StartCoroutine(UpdateStopMusicWithFade(activeSource, transitionTime, musicVolume));
}
public void PlayMusicWithCrossFade(AudioClip musicClip, float musicVolume, float transitionTime = 1.0f)
{
//Determine which source is active
AudioSource activeSource = (firstMusicSourceIsPlaying) ? musicSource : musicSource2;
AudioSource newSource = (firstMusicSourceIsPlaying) ? musicSource2 : musicSource;
//Swap the source
firstMusicSourceIsPlaying = !firstMusicSourceIsPlaying;
//Set the fields of the audio source, then start the coroutine top crossfade
newSource.clip = musicClip;
newSource.Play();
StartCoroutine(UpdateMusicWithCrossFade(activeSource, newSource, transitionTime, musicVolume));
}
//Update the volume overtime to achieve a fade effect
private IEnumerator UpdateMusicWithFade(AudioSource activeSource, AudioClip newClip, float transitionTime, float musicVolume)
{
//Make sure that the source is active and playing
if (!activeSource.isPlaying)
{
activeSource.Play();
}
//transition float
float t = 0.0f;
//fade out
for (t = 0; t < transitionTime; t += Time.deltaTime)
{
//Music clip's volume is going to be reduced a bit every second
activeSource.volume = (musicVolume - ((t / transitionTime) * musicVolume));
//Makes sure this is updated over multiple frames
yield return null;
}
//transition to new clip
activeSource.Stop();
activeSource.clip = newClip;
activeSource.Play();
//fade in
for (t = 0; t < transitionTime; t += Time.deltaTime)
{
//Music clip's volume starts at 1, and for every second it is going to be reduced a bit
activeSource.volume = (t / transitionTime) * musicVolume;
//Makes sure this is updated over multiple frames
yield return null;
}
}
private IEnumerator UpdateStopMusicWithFade(AudioSource activeSource, float transitionTime, float musicVolume)
{
//transition float
float t = 0.0f;
//fade out
for (t = 0; t < transitionTime; t += Time.deltaTime)
{
//Music clip's volume is going to be reduced a bit every second
activeSource.volume = (musicVolume - ((t / transitionTime) * musicVolume));
//Makes sure this is updated over multiple frames
yield return null;
}
//stops music
activeSource.Stop();
}
private IEnumerator UpdateMusicWithCrossFade(AudioSource original, AudioSource newSource, float transitionTime, float musicVolume)
{
float t = 0.0f;
for (t = 0.0f; t <= transitionTime; t += Time.deltaTime)
{
original.volume = (musicVolume - ((t / transitionTime) * musicVolume));
newSource.volume = (t / transitionTime) * musicVolume;
yield return null;
}
original.Stop();
}
//plays the SFX
public void PlaySFX(AudioClip clip)
{
//if we just use Play, let's say we have two SFX overlapping, Play will just mute the previous audio clip
sfxSource.PlayOneShot(clip);
}
//plays the SFX, but allows to change the volume
public void PlaySFX(AudioClip clip, float volume)
{
sfxSource.PlayOneShot(clip, volume);
}
//good for options menu
public void SetMusicVolume(float volume)
{
musicSource.volume = volume;
musicSource2.volume = volume;
}
public void SetSFXVolume(float volume)
{
sfxSource.volume = volume;
}
}
```