I’m attempting to have an “Audio Controller” in my game where I can store most of the game audio. I have a static variable in the Audio Controller script that can be accessed without needing an instance of the class. Or so I thought.
Here is the Audio Controller script set to an empty object:
public class AudioController : MonoBehaviour {
AudioSource audio;
public AudioClip wpnPowerUp, powerUp;
public static AudioController audioController;
void Start()
{
audio = GetComponent<AudioSource>();
}
public void WpnPowerUp()
{
audio.PlayOneShot(wpnPowerUp, 1.0f);
}
public void PowerUp()
{
audio.PlayOneShot(powerUp, 1.0f);
}
}
Here is an example of a script attached to pick ups in the game. This script will access Audio Controller to play the necessary sound:
public class PowerUpBehavior : MonoBehaviour {
void Start ()
{ }
void Update ()
{ }
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Player")
{
if (gameObject.tag == "WeaponPowerUp")
AudioController.audioController.WpnPowerUp();
if (gameObject.tag == "ShieldPowerUp" || gameObject.tag == "LifePowerUp")
AudioController.audioController.PowerUp();
Destroy(gameObject);
}
else
Physics.IgnoreCollision(collision.collider, GetComponent<Collider>());
}
}
I’m getting the error on these two lines:
AudioController.audioController.WpnPowerUp();
AudioController.audioController.PowerUp();
I’m lost in the woods here, been looking at this for hours. No idea.
The problem is that inside your AudioController class you are basically exposing another AudioController, which is unfortunately completely uninitialized! Instead you should be making the methods that you want to expose to the rest of your project static,
i.e WpnPowerUp and PowerUp()
and remove:
public static AudionController audioController entirely.
From a software design perspective I would also recommend to look at the Singleton Pattern for your use case. Good luck!
Thanks for the answer gentlemen. It turns out I needed a combination of both of your answers to get this right.
I assume Singleton would not work for this class as there is the possibility that this class will exist in more than one place at the same time. IE: player picks up a power up while enemy ship is exploding somewhere, thus two sounds are being played.
@fvde What would be the down side of making a static object? I assume there is a security issue there or something? I simply would think it’d be easier to make a static object instead of making every method in the class static. Clearly you’ve more experience with this than I do. Your thoughts?
You know everybody around here always just asks how things can be done the fastest, easiest and forgets completely that their fast hack will cost them ten times the time in a month when searching for that one ridiculous bug or refactoring - so thank you for taking the time
It boils down to software development principles: never expose more to the outside then what is absolutely necessary. Sure, right now it will be faster to write static object once and be done with it, but it will hurt you in the long run. You may start using things from AudioController just because they are there and exposed - and after a few months you find yourself with a big blob of code that makes calls in all directions. For any function or property you should - imo - ask yourself everytime: Does anyone need this? Can I keep audio logic in my AudioController? How to expose as little to the rest of the project as humanly possibly.
This kind of thinking may (!) help keep your project clean, lean and easily testable in the future. Good luck!
All that makes perfect sense. My code for my game has grown exponentially since I started working on it. I can see how things can get confusing quite quickly.