Speed built-in parameter question

Hello everyone.

I’ve been experimenting with 2.0.0’s new features. Kudos on those by the way, great stuff! One of the features that caught my eye was the Speed built-in parameter, but I cannot seem to be able to make it work, which leads me to believe that I may have misunderstood its functionality.

To test things, I created an event and on its Timeline sheet I placed a temporary, very short sound (just to monitor event output in Unity; let’s call it ‘feedback sound’) and a loop region on the Timeline sheet, so that the event would keep playing once started (since the event would stop immediately otherwise, as I intended to remove the feedback sound later). Then I added the built-in Speed parameter and placed an audio asset on its sheet (let’s call it ‘main sound’) spanning from 0.1 to 10, so that it would only play that sound if the object the event was attached to was moving, even in the slightest. Finally, I put an FMOD spatializer on the event’s master track. In Unity, I attached the event to the Player’s feet, since I intend to use the Speed parameter functionality in a footsteps event for a first-person character (player doesn’t move: no sound, player moves slowly: soft footstep, player moves quickly: hard footstep. Simple, effective, no coding required, less hassle/debugging; it’s ideal!). I then hit Play, started moving around, and I could only hear the feedback sound, and never the main sound. I could see that the event was playing alright, but the Speed value was presumably staying at 0 value. To make sure there was nothing wrong with the main sound itself, I tried dragging its module on the Speed sheet to cover the 0 value as well, and the main sound then played ok.

I was baffled. I took a look at the documentation again.

The new speed built-in parameter is automatically set to the speed of the event instance it’s used in (determined by the velocity of the event instance relative to that of the listener). This can be used to automate properties of an event instance based on how fast it is moving.

The way I had interpreted this the first time around, was that FMOD calculated the speed based on the changes of an event’s/gameObject’s 3D attributes alone, which made perfect sense. But, now, I started wondering whether it was possible that the ‘relative to that of the listener’ part meant that the parameter took the Listener’s 3D attributes under consideration as well, but even though this makes perfect sense in, say, the Distance built-in parameter’s case, I failed to see how the Listener’s position would have anything to do with any other gameObject’s Speed. If that really were the case though, it might mean that the Speed value of my event would always be 0, as the Player’s feet, on which I had attached the event, stayed in the same relative position to its parent gameObject, which in turn contained the Listener. And, if that were the case as I said, though Speed would nevertheless remain an awesome feature, it would be a no-no for my player footsteps scenario. Regardless, I decided to put this to the test. I created a cube in Unity, and added some basic animation to it. Then I removed the event from the Player’s feet, attached it to the cube, and pressed play. The cube was moving (at different speeds and across all three axes), the feedback sound with it. Again, though, the main sound never played. I even tried walking around with my character, and still seemingly no change in Speed. Through code I printed the event’s Distance, Elevation and Speed (final)values (I added Distance and Elevation sheets for that), and could see that, while the cube was moving, the Distance and Elevation values kept changing, but the Speed value was fixed at 0.

Why is this happening? And are the Listener’s 3D attributes indeed needed for the Speed to be computed? If so, would that mean I cannot use the parameter the way I intended?

On a side-note, why is it that built-in parameters cannot be global? That would come in handy if, for instance, other events needed to know the Distance/Elevation/etc of a certain event. And making that information global (without the use of code) cannot even be achieved indirectly, by automating a global parameter based on a built-in parameter, since global parameters “can only be automated by a global parameter”. A very nice case of catch-22.

I am sorry for the excruciating post length, and thank you for your time and for the awesome features!

Much love!

That’s correct: “Relative to the listener” means that if the listener is moving in lockstep with the emitter, the speed parameter’s value will remain at zero.

How exactly were you moving the cube in Unity?

If you used transform.position then the speed parameter remaining at 0 is totally expected, because that function doesn’t “move” an object so much as “change its location.” It bypasses Unity’s physics engine, and thus Unity’s calculation of object velocity, and so the object’s speed never rises above 0. Changing the location of an object this way is useful if you truly do want it to be in a different location without having to travel there - teleportation and motionless space-warping are features of many games - but it’s not appropriate for objects travelling through normal space.

If you want an object to have velocity, you need to move it using some function that works within Unity’s physics system, such as Rigidbody.position or Rigidbody.MovePosition.

A parameter based on a global parameter is, by definition, set to the value of that global parameter. A built-in parameter is, by definition, set according to the 3D attributes of the event instance. A parameter cannot be both global and built-in because such a parameter would have to be set to two different values simultaneously.

You’re right that it might sometimes be useful to know the value of a local parameter globally. It’s already possible to get the value of a parameter via the FMOD Studio API, but I’ll investigate and see whether there’s any ways we might make this easier to use through FMOD Studio.

1 Like

Thank you for the swift reply!

I was moving the cube with Unity’s Animation component, but, it had no rigidbody. As soon as I added one, the event played out as expected. Pity that I cannot use it in Player footsteps. Oh well, at least now I can name the surface parameter values properly and not 0, 1, 2, 3. :grin:

I am not sure if I understood what you are saying correctly, but the way I thought this worked is one parameter is essentially automated based on the value of another (global) parameter, and the two don’t necessarily share the same value. Their values are merely paralleled/connected, but not both ways; only the one parameter’s value affects the other one’s and not vice versa.

I hear you, but what if the parameter was also read-only, unchangeable via the API, as all built-ins are? That way the global/built-in parameter’s value would be readily available to any other parameter that might wish to automate its own value according to it, but it would not be accessible to change ‘externally’.

I am sorry if I come across as presumptuous, I know features might not be as easy to implement/incorporate as us end-users might foolishly assume sometimes.

Thank you again for your time.
Have a great one. :slightly_smiling_face:

Let me put it this way:

  • A local parameter can have a whole bunch of values, such that each and every instance of that parameter can be different.
  • A global parameter has one value. It’s the same everywhere, in every event instance that uses that parameter in any way. Changing the value of that parameter anywhere changes it “globally” because there’s only one value to change.

The values of built-in parameters are based on the 3D attributes of event instances, and that means that they can be different for each and every event instance. Having a different value for each event instance is incompatible with having a single value globally.

I’m afraid I don’t understand what you’re suggesting.

A parameter being read-only just means it can’t be set via a function call in the game code; it can still change in value due to automation, modulation, or due to being set by an event instance’s 3D attributes. This is true regardless of whether the parameter is local or global. Setting the parameter to read only won’t have any impact on whether the parameter has one global value or many local values, nor on whether the parameter’s value can be observed externally or used to control the values of other parameters via automation.

1 Like

As always, everything is clearer now that you’ve explained it. Of course, it makes sense. I wasn’t taking into account the possibility of multiple instances, hence multiple values… Forget I said anything! :smile: