Class statics, instances and scenes

Kind of vague questions that I am tempted to try to answer by trial and error but afraid I might get away with breaking “da rules” in small tests that don’t work in larger projects because of more active GC or whatever.

Some background…
I am new to Unity but not to C#. I have been using it professionally for about 15 years. I consider myself a pretty advanced user. I am working with audio. I kind of came in through a side door. I am looking to develop my hobby of music composition into a side gig and then maybe my only gig for semi-retirement in two or three years. Anyway, I pretty quickly discovered what you probably know - there are a ton of people trying to do music for games and it is difficult to get started. I looked into the engines and found that Unity was a very friendly environment for me, so I learned a bit about the audio objects (probably not enough yet) and offered to collaborate with independent game devs to add the music and/or sound effects into games. That worked and I am now doing some development. It’s going well, but I am getting far enough into it to start thinking about a good general approach that isn’t snippets here and there with AudioSource hung off objects all over the place.

OK, actual questions…
I know that scripts are classes and that every time you attach one Unity creates an instance. But I wonder about class statics. Are class statics completely global? So that a value set at any point on any scene will retain the value until changed or the game ends?
What happens if you set a static member variable to an object in one scene when you switch to another scene?
Is it possible to create global instances of AudioSource and AudioClip objects?
Can you dynamically add scripts (creating an instance) to objects at run time?
And finally, is there a GameObject that is always “live” through the whole game that I can add components to?

I thought about breaking this up into multiple questions but they are kind of interrelated. I am doing some dynamic loading and switching of AudioClips and making sure I have AudioSources where I need them and finding I am doing the same things - applying music or in game sound volume to AudioSources for example - in lots of different places.

Thanks!

Yes indeed.

Nothing, unless you change it inside a function that is called by a scene change.

AudioClips are reference to sound, usually (but not necessarily) on disk. That means effectively they are static.

AudioSources are Components, which means you can never new one up. You must always have a GameObject and call .AddComponent<>() to create them.

Just setting things static does not “save” them from scene changes. They still get destroyed, even though you have a (now-invalid) reference. To save stuff scene to scene, mark its root GameObject as DontDestroyOnLoad();

If you press pause in game you can study the hierarchy and note their is an extra “ghost” scene created called “DontDestroyOnLoad()” and things that are marked such are moved into that scene for you. They will NOT Destroy themselves when a new scene loads. You may Destroy() them yourself.

All day long! .AddComponent<>()

You may make one. In Unity there are sub-flavors of singletons. You can have singletons with varying lifecycles, which is extremely powerful.

  • You could have a true singleton: just what you think it is, one only, never another. (Such as an in-app purchasing manager, or music manager)

  • You could have one derived from MonoBehavior so it gets all those callbacks.

  • You could have one that gets destroyed automatically when scenes change (such as an enemy wave manager).

  • You could have one you create at the start of the game, and it persists until your game session is over (powerup manager, inventory manager, etc.)

Anything that is a MonoBehavior has these timing properties:

https://docs.unity3d.com/Manual/ExecutionOrder.html

Simple Singleton (UnitySingleton):

Some super-simple Singleton examples to take and modify:

Simple Unity3D Singleton (no predefined data):

https://pastebin.com/SuvBWCpJ

Unity3D Singleton with Prefab used for predefined data:

https://pastebin.com/cv1vtS6G

These are pure-code solutions, do not put anything into any scene, just access it via .Instance!

1 Like

This is exactly what I am hoping to do. I have just been working in four scenes so far and it is a pain working out ownership with the game dev so I can change a scene just to add an object and hang a script off of it. I did discover the SceneManager which I am using to have slightly different behavior in the same class.

I like the code only idea for portability. I am about to start working with another game dev and want to use as much of the same code as possible. I also like that it can make my code more like an API that isn’t so intertwined with the rest of the project. My offer to help get the audio into games is most attractive to people without a background in development and the existing structure can be interesting. I am being a little selective; there needs to be enough there that some snippets will look good in a demo reel when it has music and sound effects. Sound effects is proving to be more of a pain as it does require more integration, but it’s interesting.

Thanks for the incredibly thorough response. I really appreciate it. I have learned more from you in a few paragraphs than from hours of Google and YouTube…

1 Like