The title is actually self-explanatory. I would like to know if there are any drawbacks (performance-wise, good-practice wise, etc.) for having multiple audio sources on the same GameObject. My initial intuition is that it gives me more freedom to have specific audio settings (volume, pitch, etc.) for each audio clip I want to play, but I want to know if this setup is advisable.
-
\$\begingroup\$ What does your profiler tell you about the cost? I'd trust that over hearsay from Internet strangers like us. 😉 \$\endgroup\$– DMGregory ♦May 20, 2021 at 9:50
-
2\$\begingroup\$ I would go with what is most comfortable for fast creating/changing and only worry for performance if/when it becomes in issue (which is rare for smaller scale games). \$\endgroup\$– NikaasMay 20, 2021 at 10:27
2 Answers
As I was taught on anything about software development: it depends.
Back in the days, memory and CPU were limited resources, and devs had to be extremely careful about data and cycles used by their software. An old-school video game would feature just a handful of mono sound effects (or background music only). Current video games exploit the power of end-user machines by playing multiple surround sounds for additional immersion.
It isn't bad to have multiple sound sources in your game, and it isn't necessarily a bad idea to assign different Audio Sources to the same object. After all, it would be quite odd if we could hear a character's footsteps originating from their head because we assigned one sound source only! On the other hand, it would be overkill to create too many specific sources for any possible sound your character could emit: footsteps, hands, voice, something in their pocket...
In Unity, the Audio Source component plays back an audio clip and defines the audio settings to apply (in the inspector). But, it only does so when we order it to; all other times, it's just storing (basically immutable) values. Performance is more about filtering sounds at runtime and streaming output audio. The Audio Profiler can help you with that by showing a lot of information useful for debugging. If too many sounds are playing at once, you will know. You can also limit the max number of real voices to limit the number of sources actually playing and reduce CPU usage. Besides, if the listener can't hear a specific sound, then it won't be played back. This is similar to graphics: even if an object mesh has a high number of vertices, there's no rendering overhead if the object isn't visible to the camera.
A sound position isn't tracked directly because it derives from the Transform the Audio Source is attached to, for free. Then, if you want different Sources moving around, you need to attach them to different Transforms in a GameObject hierarchy (like any other Component), and that's by design: the engine performs a huge number of matrix operations each update, so a couple more are not going to be a big deal. There are few meaningful cases for having multiple Audio Sources in the same GameObject, like the need for very different audio settings at the same 3D position, though these are uncommon.
A good practice to follow is limiting the number of resources as long as the final result is acceptable: I would go with 3 Audio Sources on a character: one for their mouth (at the top), one for their body (at the centre of mass), and another one for their feet (at the bottom). All additional sounds can be played by audio sources attached to different objects, or on-demand at a specific location.
-
\$\begingroup\$ The example you describe has all the sound sources on separate transforms, so seperate gameObjects... \$\endgroup\$ May 20, 2021 at 16:56
-
\$\begingroup\$ Yes, you're right. I assumed OP was talking about objects as whole entities (e.g. Prefabs) rather than individual GameObjects in the hierarchy. I updated my answer to address this as well. \$\endgroup\$ May 20, 2021 at 18:21
While you can have multiple AudioSources on one GameObject, I would recommend creating multiple child GameObjects under one parent GameObject with one AudioSource on each child, because:
calling
GetComponent
on a GameObject will only return the first AudioSource it finds, andclicking and dragging AudioSources into reference fields in the Inspector tab will always show the name of the GameObject, which does not help when there are multiple AudioSources on the same GameObject.
By having multiple child GameObjects with one AudioSource each, you can name each GameObject appropriately regarding the sound, which alleviates confusion as to which AudioSource is being referenced.