I’m working on a client’s game and I’m having trouble triggering a parameter change.
The game has a prefab called DarkMatter which triggers my local Perk parameter to update when the prefab is created. The emitter using this parameter is on the PegBasic prefab which triggers on Collision Enter 2D.
From what I can see, the issue might caused by timing: your Studio Parameter Triggers fire on Object Start/Disable, but the Studio Event Emitter on PegBasic only creates the event instance on Collision Enter 2D. When the triggers run, there’s no instance yet, so the local Perk parameter isn’t applied. Later, when the collision occurs and the instance is finally created, it uses the event’s default parameter value, which makes it seem like the parameter change didn’t work.
Thanks for your input! That makes sense and I’ve changed the PegBasic prefab to trigger on ObjectStart, though no change. I’ve checked the specific instance of the peg to see if it updates, though the parameter is still None.
I also tried removing an initial parameter value from the PegBasic prefab, though this didn’t help. Is this something I’ll need to change in the code? I popped a couple of debugging messages in the Play() and TriggerParameters() functions and it revealed Play() isn’t actually running at all, not even when the trigger is Object Start.
Could you please share a small code snippet showing how/where you play the sound (e.g., the Play() call and any parameter writes)? That’ll help me see the timing/order.
Also, could you please set Logging Level to Log and Enable API Error Logging (FMOD → Edit Settings), then try to play the sound and attach the full log so I can take a closer look?
public void Play()
{
// UnityEngine.Debug.Log($"[FMOD] Play called on Event Emitter with Event '{EventReference.Path}'");
if (TriggerOnce && hasTriggered)
{
return;
}
if (EventReference.IsNull)
{
return;
}
cachedParams.Clear();
if (!eventDescription.isValid())
{
Lookup();
}
bool isSnapshot;
eventDescription.isSnapshot(out isSnapshot);
if (!isSnapshot)
{
eventDescription.isOneshot(out isOneshot);
}
bool is3D;
eventDescription.is3D(out is3D);
IsActive = true;
if (is3D && !isOneshot && Settings.Instance.StopEventsOutsideMaxDistance)
{
RegisterActiveEmitter(this);
UpdatePlayingStatus(true);
}
else
{
PlayInstance();
}
}
I tried adding some debug logs in StudioParameterTrigger.cs to figure out where exactly the issue is. Even when setting the PegBasic event emitter trigger to Object Start, the target (PegBasic) is never valid and the the parameter never triggers.
public void TriggerParameters()
{
for (int i = 0; i < Emitters.Length; i++)
{
var emitterRef = Emitters[i];
UnityEngine.Debug.Log($"[FMOD] Trigger Parameter Target: {emitterRef.Target}. Target Valid: {emitterRef.Target.EventInstance.isValid()}.");
// FIXME: Perks don't update local Perk parameter for PegBasic - isValid() is
if (emitterRef.Target != null && emitterRef.Target.EventInstance.isValid())
{
for (int j = 0; j < Emitters[i].Params.Length; j++)
{
emitterRef.Target.EventInstance.setParameterByID(Emitters[i].Params[j].ID, Emitters[i].Params[j].Value);
}
}
}
}
Been chatting with the devs about this and I think we’ve found the issue.The lead dev isn’t a programmer and they’ve made this entirely with PlaymakerFSM, so they aren’t following common Unity programming conventions. In this case, PegBasic instances aren’t being instantiated in the traditional sense, they’re preloaded into a parent prefab. The Emitter’s Play() method never runs because the object is never ‘created’, so naturally TriggerParameter() can never find the PegBasic instance.
We’re working on a way to fix this that doesn’t require creating every instance of a peg (this would slow down the game significantly), unless there’s a way for Emitters to trigger for objects created at runtime.
Thank you for providing extra details and the log!
It looks like the log confirms your findings: the parameter triggers fire before any EventInstance exists because Play() never runs. Since the pegs are preloaded and don’t hit the usual Unity lifecycle hooks (Start/OnEnable), the StudioEventEmitter won’t play automatically.
Two approaches that might fit your workflow:
Trigger a lifecycle: pool pegs as inactive, set emitter to OnEnable, then SetActive(true) when used. This ensures Play() happens before you set parameters.
Control it explicitly: from Playmaker or a tiny bridge script, call emitter.Play() (or create/start an EventInstance directly) and then set the Perk parameter, which is commonly recommended for runtime driven behavior. You can find a related discussion here: Changing a SudioEventEmitter's Event During Runtime - #2 by Leah_FMOD