Is it a good idea to make an AudioSource a static variable?

I’m torn between using that:

public GameObject screamObject ;
public static AudioSource screamSource ;

screamSource = screamObject.GetComponent<AudioSource>();

And then I can play that sound from any script:

theSoundScript.screamSource.Play();

OR…

Should I make of screamSource a public variable (dragged through inspector), a local function called PlayTheScreamSound() and then, in all my scripts I do that:

theSoundScript = theSoundObject.GetComponent<theSoundScript>()
theSoundScript.PlayTheScreamSound();

Some of my sounds will be played very often and some others very rarely. Should I use the static variable option for the frequently played ones?

Performance- and memory-wise, what is the best option?

Thanks in advance.

Performance-wise there might be a slight difference, memory-wise probably nothing significant. This crops up from time to time.

I’d say it’s a matter of taste, though. I like to keep objects as independent as possible, and use a few specialised singletons for managers. A sound manager is possibly a better case for a singleton, or a whole static class. I also think it’s better to optimise the sound effects to play down to a switch statement, and use an integer enum to select. Then you just call SoundManager.PlayEffect(Effect.Scream) or something like that.

Performance and memory wise I don’t think you’re going to see much difference with any solution here.

Using a static for one thing is convenient, but you’ll quickly find that as your application grows things get very confusing very quickly, and you have weird dependencies all over the place.

Furthermore, in your first example snippet, it looks like every instance of your object would reassign screamSource, which isn’t awful, but it isn’t great either.

I think you’re onto something with your second snippet. You could easily write a soundboard script that holds audio logic. You could provide this soundboard instance to each new MonoBehaviour you instantiate as required. This is much more OOP friendly and easier to maintain.

Finally, do many of your objects need access to the audiosource? Perhaps you are better served by passing an event up your hierarchy and the parent can be responsible for audio, e.g.:

public class Player : MonoBehaviour
{
    public event EventHandler onDeath;

    private void OnDeath()
    {
        EventHandler handler = onDeath;
        if (handler != null)
            handler(this, EventArgs.Empty);
    }
}

This is nicer because you decouple your player from the soundboard, meaning you can reuse your objects without worrying about dependencies.