Pooling instances manually vs creating new instances

Hi! I am very new to using FMOD in unity, but I would like to get the optimal approach right before starting.

What I am wondering about right now is the performance of creating an instance every time I need a sound in our tycoon game, vs having a pool of objects with their own script and each with their own persistente instances to use from the pool.

Is the second approach worth the hassle, or behind the scene the creating of new instances in FMOD is already handled in a pool-like way and it’s already optimized?

Thanks and cheers!
Dr.H

Mhm the more I dig into it, the more I realized I don’t understand some basic behaviors I guess.

My original doubt from the topic, evolved into something more specific (not that the previous one has been solved yet :stuck_out_tongue: ):

When I play a one shot sound with spatial positioning, do I also need a specific emitter for it? Let’s say one of my characters burps (they are little drunk brewing monks), so it’s a one-shot-like sound, and I want to play it on the monk position. Do I need to instantiate a sound emitter to that position in order for the sound to be spatially heard, or by just calling play one shot with the position, there is already an emitter-like behavior happening behind the scene?

If an emitter is needed, the I guess my original pooling idea should evolve into something like having a pool of objects with emitters, and on need, fetching one object from the pool, attaching it to the character, assigning it the right event and playing the sound. Would this make sense or it’s again some convoluted way that I am looking for to do something otherwise simpler?

To answer your question directly, instances aren’t pooled by FMOD. I wouldn’t worry too much about performance from FMOD when doing this - if you’re trying to play an event instance per GameObject, ultimately you will need to do that, so the impact will likely come from how instantiation of GameObjects and Components is happening instead. That said, it is worth noting that if you want events to play ASAP when prompted, creating them ahead of time is recommended.

However, I think this is a question that goes beyond just the performance of a pool of objects, and also relates to the overall structure of how the objects are managed, how the events are structured, and so on. My response is going to be a bit general as a result, since I’m not familiar with the complexities of your game.

Having an object manage the lifespan of a single event, or several events (i.e. multiple kinds of SFX) is relatively common, and the Studio Event Emitter component was designed with this in mind. However, many events are not structured to be handled in this way - for example, one-shot events that are designed to played and immediately released. If your objects are handled more on a per-object basis, having each objects manage its own persistent event instances falls in line with this structure. However, if you’re doing things in a more data-driven way (i.e. some kind of ECS), creating event instances for the objects in some kind of management script (for example, using PlayOneShot on the positions of all objects) might be a better approach.

That said, for some more context I think it’d be good to elaborate on the structure of the FMOD Studio API, and how the Unity integrations interacts with it.

Using the Studio API, you can create and play event instances. These can be positioned in space using Studio::EventInstance::set3DAttributes, which will cause them to be spatialized based on the Listener position if they have a Spatializer effect. Since this is an API, all of this is intended to be done via code. The FMOD for Unity integration sits on top of this, and provides management of an FMOD system, as well as a number of components to abstract the code-based nature of the API into editor functionality.

So, if you want to create and play an event and have it be spatialized, you have a few ways of doing it:

  1. Directly use the API, i.e. create an event instance, set its 3D attributes, and then play it
  2. Use a PlayOneShot function from the FMOD for Unity class RuntimeManager, i.e. PlayOneShot or PlayOneShotAttached
  3. Create/instantiate a GameObject that uses a Studio Event Emitter component to play an event

Note that 2 and 3 are both using the same functions as 1, so ultimately which is best depends on what you need and your workflow. Are you working at a higher level with GameObjects only? 3 might be the best. Do you need to use the API for lower-level/more advanced control of your events? 1 is best (and goes well with more data-driven systems). Are you using code, but don’t want/need the complexity of the API for your use-case? 2 would be the best.

For more info, I’d recommend reading over the FMOD Studio API Guide, and then taking a closer look at the code for the FMOD for Unity classes (i.e. Studio Event Emitter) to see exactly what they’re doing. Some of our Unity example scripts, such as the Basic one, should help to demonstrate how to interact with the API and Unity integration.

Hi, and thank you very much for the very good explaination. I think it gives me the foundation to start thinking a bit more clearly about the way I shall use FMOD in our project.
Our project is quite large and data-driven, and we tend to work at the lowest (reasonable) level for our project, therefore I guess you answered perfectly one of our unasked questions too.
We’re lucky enough to work with a very experienced FMOD sound designer (Clint Bajakian, formerly Lucas art and Sony), now it’s up to us programmers to catch up on the Unity side :joy:
Cheers and thanks a lot, I guess soon I will be back with more questions!

Happy to help! Feel free to let us know if/when you have any more questions.