Unity custom Audio Manager won't work with custom Stop function
Hello there, I made an Audio Manager using Brackey's tutorial. The Play() function works perfectly, but here's how my music is set up.
From the start, I have a violin at the background. Whenever I get into combat I want this violin to stop, and the action music to start. However, whenever I want to start the game, I get a NullReferenceException and can't manage to figure out what the problem is, because I have an if (fadePlaying != null)
before the whole thing works in the Update. This error makes the whole function not work (I think). The scripts:
using UnityEngine;
using UnityEngine.Audio;
[System.Serializable]
public class Sound {
public string name;
public AudioClip clip;
[Range(0f, 1f)]
public float volume;
[Range(0.1f, 3f)]
public float pitch;
public AudioMixerGroup mixer;
[HideInInspector]
public AudioSource source;
}
using UnityEngine;
using UnityEngine.Audio;
public class AudioManager : MonoBehaviour {
public Sound[] sounds;
public AudioManager instance;
public Sound currentlyPlaying;
public Sound fadePlaying;
void Awake()
{
if (instance == null)
instance = this;
else
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
foreach (Sound s in sounds)
{
s.source = gameObject.AddComponent<AudioSource>();
s.source.clip = s.clip;
s.source.volume = s.volume;
s.source.pitch = s.pitch;
s.source.outputAudioMixerGroup = s.mixer;
}
}
void Start()
{
Play("Theme");
}
void Update()
{
if (currentlyPlaying != null)
{
if (currentlyPlaying.source.volume < 1)
currentlyPlaying.source.volume += Time.deltaTime;
}
}
public void Play(string name)
{
currentlyPlaying = Array.Find(sounds, sound => sound.name == name);
currentlyPlaying.source.Play();
}
public void Stop(string name)
{
fadePlaying = Array.Find(sounds, sound => sound.name == name);
while(fadePlaying.source.volume > 0)
{
fadePlaying.source.volume -= Time.deltaTime / 3;
}
}
}
And the little part in the Player that's supposed to manage the changes:
if (isDetected)
{
if (!hasPlayed)
{
FindObjectOfType<AudioManager>().Play("Action Music");
hasPlayed = true;
}
if (FindObjectOfType<AudioManager>().currentlyPlaying.name == "Theme")
FindObjectOfType<AudioManager>().Stop("Theme");
}
else if (!isDetected)
{
if (FindObjectOfType<AudioManager>().currentlyPlaying.name == "Action Music")
{
FindObjectOfType<AudioManager>().Stop("Action Music");
if (FindObjectOfType<AudioManager>().currentlyPlaying.source.volume == 0)
hasPlayed = false;
}
}
Thank you a lot for taking your time and reading this, it really means a lot to me.
Do you have an Audio$$anonymous$$anager in your scene? If not, FindObjectOfType()
will return a null, and you never check for that. In general, always check the result of FindObjectOfType()
, GetComponent()
, and similar calls, because there might be nothing that fits your search.
Btw, your Audio$$anonymous$$anager class is a singleton so that you don't need to look for it, you can use Audio$$anonymous$$anager.instance
to access it from anywhere (after a null check, of course ;) ).
If this is not the issue, then you should also check if Array.Find()
in Audio$$anonymous$$anager.Play() return anything... maybe the audio files have different names than what you think (Unity usually cuts off the file extension).
Hello there,
There is always one instance of an Audio $$anonymous$$anager in a scene. And I checked the names, this is also not the issue.
Then it's debugging time! Either add null checks everywhere and print Debug.Log("... is null!");
if it is null, or if using Visual Studio, add breakpoints everywhere, especially in Awake() and Start() methods, and start in debug mode stepping through until you find what exactly is null.
Sorry, with this much info this is all I can offer.
Answer by unity_ZhFa2_SEDiZheg · Jun 19, 2020 at 09:42 AM
Hello, i found same problem and here is the fixing;
You should include this "VOID" on your audioManager Script, so you can call this function in any scripts like you do to Play.
public void Play (string name) { Sound s = Array.Find(sounds, sound => sound.name == name); if (s == null) { Debug.LogWarning("Sound: " + name + " not found!"); return; }
s.source.Play();
}
**public void Stop (string name)
{
Sound s = Array.Find(sounds, sound => sound.name == name);
if (s == null)
{
Debug.LogWarning("Sound: " + name + " not found!");
return;
}
s.source.Stop();**
}