I have 2 parameters “IsInteriorCamera” and “IsPlayer”:
“IsInteriorCamera” is global, and while it’s typically either 0 or 1, it smoothly transitions between them during a camera switch animation (and these animations are not a consistent length).
“IsPlayer” is per event (e.g. if it’s “footstep” then that can be either from the player or from an NPC and they have different FX applied). It’s only ever 0 or 1.
I need a 3rd parameter: “IsInteriorCameraOnPlayer”. This parameter should only be 1 if “IsInteriorCamera” is 1 and “IsPlayer” is 1. And in fact during that camera-switch animation, if “IsInteriorCamera” is 0.25 and “IsPlayer” is 1 then “IsInteriorCameraOnPlayer” should be 0.25.
Is there a way to synthesise “IsInteriorCameraOnPlayer” entirely inside FMOD studio? I can’t just do a basic parameter automation because if “IsPlayer” is 0 and “IsInteriorCamera” is 1, “IsInteriorCameraOnPlayer” will be 0.5, but it needs to be 0.
In other words… I want to combine those 2 parameters using multiplication, not their average.
Currently I’m doing it in C#, but it means I need to remember every event which cares about “IsInteriorCameraOnPlayer” - including one-shots - and make sure that they are all updated if the camera changes plus during the animation (though maybe I could automate the Speed of a Seek modulation, haven’t tried that).
It would be way more efficient and convenient if it were just possible inside FMOD Studio since I’d only need to update that single global value. Using 2.03 by the way.
As of the time of writing (March of 2026) it is not possible to combine automation values in any way other than averaging them.
However, there are ways to get the behavior you want.
Here’s how to do it:
Don’t automate the “IsInteriorCameraOnPlayer” parameter on the “IsInteriorCamera” and “IsPlayer” parameters. It should not be automated on any parameter.
Create a parameter sheet for the “IsInteriorCamera” parameter.
On the new parameter sheet, add two command instruments: One at parameter value 0, and the other at parameter value 1.
Set both command instruments’ command types to “Set Parameter,” and set both their targets to the “IsInteriorCameraOnPlayer” parameter.
Set the value of the command instrument at parameter value 0 to 0, and set the value of the command instrument at parameter value 1 to 1.
Expand each command instrument’s trigger behaviour drawer, and give it a trigger condition based on the “IsPlayer” parameter, such that the command instrument only triggers if the “IsPlayer” parameter is 1.
Add a seek modulator to the “IsInteriorCameraOnPlayer” parameter, to ensure its value changes smoothly rather than instantly jumping whenever it changes.
Remove the seek modulator from the “IsInteriorCamera” parameter, as it’s redundant with the seek modulator on the “IsInteriorCameraOnPlayer” parameter. (This step is technically optional; feel free to keep the second seek modulator if you’re also using the “IsInteriorCamera” parameter for something else.)
If you follow these steps, changing the “IsInteriorCamera” parameter will set the “IsInteriorCameraOnPlayer” of events whose “IsPlayer” parameters are set to 1, but will have no effect on events whose “IsPlayer” parameters are set to 0. When such an event’s parameter value is changed, it will ramp smoothly from its old value to its new value.
You will, of course, need to reproduce the same parameter sheet and command instruments in every event you want to exhibit this behavior. I recommend creating the command instruments once and then copying and pasting them from one event to another.
I should mention that this method does not allow you to set “IsInteriorCamera” to arbitrary values between 0 and 1 and have “IsInteriorCameraOnPlayer” set itself to the exact same values. I imagine you’re unlikely to want to do that; but if you need to, you should use the following method instead:
Don’t automate the “IsInteriorCameraOnPlayer” parameter on “IsInteriorCamera” and “IsPlayer” parameters. It should not be automated on any parameter.
Create a command instrument that’s triggered repeatedly and frequently (perhaps due to a very short loop region on the timeline, or a parameter whose value rapidly oscillates due to an LFO modulator).
Set the command instrument’s type to “set parameter,” and set its target to the “IsInteriorCameraOnPlayer” parameter.
Automate the command instrument’s value property on the “IsInteriorCamera” parameter, such that the the value of the value property is always equal to the value of the “IsInteriorCamera” parameter.
Expand the command instrument’s trigger behavior drawer, and give it a parameter trigger condition based on the “IsPlayer” parameter, such that the command instrument only triggers if the “IsPlayer” parameter’s value is 1.
Add a seek modulator to the “IsInteriorCameraOnPlayer” parameter, to ensure its value changes smoothly rather than instantly jumping whenever it changes.
Remove the seek modulator from the “IsInteriorCamera” parameter, as it’s redundant with the seek modulator on the “IsInteriorCameraOnPlayer” parameter. (This step is technically optional; feel free to keep the second seek modulator if you’re also using the “IsInteriorCamera” parameter for something else.)
This second method is more flexible than the first, but requires more work to set up and maintain.
Interesting, thanks Joseph. Yes that works quite well. I do have quite a lot of events which need this behaviour but that should be fine, it’s pretty simple to set up and copy-paste a parameter sheet.
I do actually need to have both IsInteriorCamera and IsInteriorCameraOnPlayer to be the same values, or at least for both to be able to seek at the same rate. I think I can achieve this by varying your first method:
add a global “IsInteriorCameraImmediate” parameter
add a global “IsInteriorCameraAnimationSpeed” parameter
I will set “IsInteriorCameraImmediate” from code, not “IsInteriorCamera”.
at the same time set “IsInteriorCameraAnimationSpeed” to whatever that is (might be immediately, might be 0.2/s, whatever)
Change “IsInteriorCamera” to be automated off the value of “IsInteriorCameraImmediate” with a Seek modular, its Speed determined by “IsInteriorCameraAnimationSpeed”
“IsInteriorCameraOnPlayer” gets the same seek automation.
and the parameter sheet to be used for this whole thing is “IsInteriorCameraImmediate” not “IsInteriorCamera”
I’ve noticed that there is a very slight lag between starting the event and that “IsInteriorCameraOnPlayer” value being set, like… 10-20ms. Usually not a big deal but we have some high transient gunfire and it catches the very start of it.
I can work around it by always setting both “IsPlayer” and “IsInteriorCameraOnPlayer” together from C#. However, I can’t do the same for changes to “IsInteriorCamera” (the whole point of this question). In practice this isn’t super noticeable for us because we have no transients that fire on camera changes. But, I presume that there is still a 10-20ms lag here which is a bummer. I need to test more to see if this is subconsciously noticeable. In any case just something to keep in mind.
(I was actually going to mention a potential bug where command instruments can’t seem to set the values of read-only parameters, but given I need to do this workaround anyway, it’s moot for me)
That’s to be expected: The “IsInteriorCamera” parameter is being set by a command instrument in the event. That means that the instrument can be triggered only after the event instance starts, which means that the command sent to the Studio update thread by that command instrument can only be processed by a later Studio::System::update call than the Studio::System::update call that started the event - and thus the parameter’s value doesn’t change until the next Studio::System::update call after the event starts. Most games call Studio::System::update every 10 or 20 ms, which explains the 10-20 ms lag you’ve observed.
If you want to avoid this lag, you will have to set the value of the relevant parameter before the event instance starts playing.
That’s not a bug. As described in our documentation on this topic, a read-only parameter’s value cannot by set by API calls. Command instruments function by making API calls (i.e.: commands). A command instrument cannot, therefore, set the value of a read-only parameter. If you want to be able to set the value of a parameter using API calls such as those issued by command instruments, you should uncheck that parameter’s “read only” checkbox.