# StudioEventEmitter SetParameter() GC

**URL:** <https://qa.fmod.com/t/studioeventemitter-setparameter-gc/23512>\
**Category:** Unity\
**Created:** [October 24, 2025, 10:48am UTC](https://qa.fmod.com/t/studioeventemitter-setparameter-gc/23512 "2025-10-24T10:48:58Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![SonarSoundSB](https://avatars.discourse-cdn.com/v4/letter/s/f475e1/32.png) [@SonarSoundSB](https://qa.fmod.com/u/SonarSoundSB)\
**Post date:** [October 24, 2025, 10:48am UTC](https://qa.fmod.com/t/studioeventemitter-setparameter-gc/23512/1 "2025-10-24T10:48:58Z")

</div>

Hello,

We’re using StudioEventEmitters for the bulk of our implementation and have noticed a lot of GC coming from them when setting parameters due to the params list lookup etc I’m guessing. This is much more noticable on parameters we set each frame of course and for things like occlusion (as seen in the screenshot below) can be quite a lot when dealing with multiple sounds.

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/fmod/original/2X/f/f674f37ba72d79eff5182bab8142319b2fa08a28.png)

I’ve made an extension method for the emitter which basically just ignores the list lookup

 ![2025-10-24_11h45_12](https://canada1.discourse-cdn.com/flex036/uploads/fmod/original/2X/9/9f87281cbb8f8a3fd56fca28f3289dafbd500255.png)

The developer would like to know if this is a safe alternative and/or if there’s any way to avoid GC by just using the raw StudioEventEmitter code?

Thanks for your time!

---

<div class="post-metadata">

**Author:** ![cameron-fmod](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/cameron-fmod/32/261_2.png) [@cameron-fmod](https://qa.fmod.com/u/cameron-fmod)\
**Post date:** [November 5, 2025, 3:12am UTC](https://qa.fmod.com/t/studioeventemitter-setparameter-gc/23512/2 "2025-11-05T03:12:31Z")

</div>

Apologies for the delay.

The StudioEventEmitter.SetParameter function uses a cache for the parameters but only when `StopEventsOutsideMaxDistance` is enabled, otherwise it would not keep track of the parameter changes when an event goes outside of max distance then comes back. This does incur some GC overhead as you have found.

What you have done is perfectly fine, as long as you are aware that the parameters could behave strangely when going in/out of max distance.

---

<div class="post-metadata">

**Author:** ![SonarSoundSB](https://avatars.discourse-cdn.com/v4/letter/s/f475e1/32.png) [@SonarSoundSB](https://qa.fmod.com/u/SonarSoundSB)\
**Post date:** [November 5, 2025, 8:26am UTC](https://qa.fmod.com/t/studioeventemitter-setparameter-gc/23512/3 "2025-11-05T08:26:24Z")

</div>

Thanks Cameron!

Ahh okay makes sense, we are using StopEventsOutsideMaxDistance but I assumed if the event is being stopped outside it’s max distance then it would have been released and therefore the parameter changes won’t affect that instance anyway, isn’t that the case?

I see there’s a cache solution to this problem here, should I implement something like this?

> [@StudioEventEmitter.SetParameter creates Garbage](https://qa.fmod.com/t/studioeventemitter-setparameter-creates-garbage/13177/6):
>
> Here is the dirt simplest way. Just install a cache between the parameters public static class FmodFix { private static Dictionary\<string, byte[]\> StringTable = new Dictionary\<string, byte[]\>(); public static byte[] Encode(string name) { byte[] results; if (!StringTable.TryGetValue(name, out results)) { results = Encoding.UTF8.GetBytes(name + Char.MinValue); StringTable[name] = results; } return results; } } public RESULT setParameterValue(string name, float value) { …

Thanks Cameron

---

<div class="post-metadata">

**Author:** ![cameron-fmod](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/cameron-fmod/32/261_2.png) [@cameron-fmod](https://qa.fmod.com/u/cameron-fmod)\
**Post date:** [November 7, 2025, 3:56am UTC](https://qa.fmod.com/t/studioeventemitter-setparameter-gc/23512/4 "2025-11-07T03:56:59Z")

</div>

> [@SonarSoundSB](#):
>
> we are using StopEventsOutsideMaxDistance but I assumed if the event is being stopped outside it’s max distance then it would have been released and therefore the parameter changes won’t affect that instance anyway, isn’t that the case?

It does get released but the intention is to reapply the parameters if/when the event comes back into range. Otherwise the event will use either the default parameter values or the values set in the editor.

As for the GC, I have made a couple of tasks for addressing the allocs generate by the current code and we will hopefully have those fixed in an upcoming release.

---

<div class="post-metadata">

**Author:** ![fendercodes](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/fendercodes/32/2971_2.png) [@fendercodes](https://qa.fmod.com/u/fendercodes)\
**Post date:** [November 12, 2025, 12:54pm UTC](https://qa.fmod.com/t/studioeventemitter-setparameter-gc/23512/5 "2025-11-12T12:54:13Z")

</div>

I’m also very keen to have those GC allocations addressed when you have time as we were calling this code every few frames to set parameters for certain events that need frequently updating. Keep us posted. Thanks!

---

<div class="post-metadata">

**Author:** ![fendercodes](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/fendercodes/32/2971_2.png) [@fendercodes](https://qa.fmod.com/u/fendercodes)\
**Post date:** [January 16, 2026, 2:33am UTC](https://qa.fmod.com/t/studioeventemitter-setparameter-gc/23512/6 "2026-01-16T02:33:54Z")

</div>

In case its useful, I made 2 helper functions that allows us to set and update parameters on StudioEventEmitter components without allocating any GC. As far as I can tell, this shouldn’t create any issues around the StopEventsOutsideMaxDistance stuff either.

```csharp
    public static ParamRef GetParameter(this StudioEventEmitter emitter, string parameterName) {
        if (emitter == null || string.IsNullOrEmpty(parameterName)) return null;

        var parameters = emitter.Params;
        if (parameters != null) {
            for (int i = 0; i < parameters.Length; i++) {
                var existing = parameters[i];
                if (existing != null && existing.Name == parameterName) {
                    return existing;
                }
            }
        }

        var paramRef = new ParamRef {
            Name = parameterName
        };

        if (parameters == null || parameters.Length == 0) {
            emitter.Params = new[] { paramRef };
            return paramRef;
        }

        var expanded = new ParamRef[parameters.Length + 1];
        Array.Copy(parameters, expanded, parameters.Length);
        expanded[parameters.Length] = paramRef;
        emitter.Params = expanded;
        return paramRef;
    }

    public static void UpdateLiveParameter(this StudioEventEmitter emitter, ParamRef paramRef) {
        if (emitter == null || paramRef == null) return;

        if (paramRef.ID.Equals(default)) {
            Debug.LogError("Could not update live parameter for StudioEventEmitter that hasn't run Lookup() yet");
            return;
        }

        var instance = emitter.EventInstance;
        if (!instance.isValid()) {
            Debug.LogError("Could not update live parameter for StudioEventEmitter that has invalid EventInstance");
            return;
        }

        var result = instance.setParameterByID(paramRef.ID, paramRef.Value);
        if (result != FMOD.RESULT.OK) {
            Debug.LogWarning($"Could not set parameter. Result: {result}");
        }
    }

```

Then, from wherever we need to, we can do the following:

```csharp
localCachedParamRef = OurStudioEventEmitter.GetParameter("ParamName");
...
localCachedParamRef.Value = newValue;
OurStudioEventEmitter.Play();

```

Or if its an event that was already playing we call:

```csharp
localCachedParamRef.Value = newValue;
OurStudioEventEmitter.UpdateLiveParameter(localCachedParamRef);

```

---

<div class="post-metadata">

**Author:** ![fendercodes](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/fendercodes/32/2971_2.png) [@fendercodes](https://qa.fmod.com/u/fendercodes)\
**Post date:** [February 20, 2026, 4:22am UTC](https://qa.fmod.com/t/studioeventemitter-setparameter-gc/23512/7 "2026-02-20T04:22:45Z")

</div>

@cameron-fmod It would be great if you could address some other regular GC allocations in FMOD scripts.

For example, `RuntimeManager.FindOrAddAttachedInstance` has some allocations and that is a function that gets called regularly. You can fix them by using a basic loop instead of `Find()` and using a pool for `AttachedInstance` rather than creating a new one each time its null.

Regular allocations are really important to avoid for games to feel butter smooth, so any work you can do to improve FMOD on that front would be greatly appreciated.

---

<div class="post-metadata">

**Author:** ![cameron-fmod](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/cameron-fmod/32/261_2.png) [@cameron-fmod](https://qa.fmod.com/u/cameron-fmod)\
**Post date:** [February 24, 2026, 3:04am UTC](https://qa.fmod.com/t/studioeventemitter-setparameter-gc/23512/8 "2026-02-24T03:04:14Z")

</div>

Thanks for the suggestion, we do have plans to address these as well as the originally mentioned GC allocations.
