Unity PlayOneShot with a specific volume?

Hello,

Is it possible to play a 2D OneShot Sound at a specific volume via Code ?
Something Like FmodStudio.RuntimeManager.PlayOneShot( string path, float volume ); ?

I am currently struggeling, because i have 2d sound effects, Triggering from various different scripts and I would like to lower the volume / mute the sound if it comes from specific instances of these scripts.

If not, do you have any recommendations how to archieve something like this ?

thanks for any advice

I think this is something you can easily change in the code. Take a look at the PlayOneShot methods in RuntimeManager.cs:

    public static void PlayOneShot(string path, Vector3 position = new Vector3())
    {
        try
        {
            PlayOneShot(PathToGUID(path), position);
        }
        catch (EventNotFoundException)
        {
            Debug.LogWarning("[FMOD] Event not found: " + path);
        }
    }

    public static void PlayOneShot(Guid guid, Vector3 position = new Vector3())
    {
        var instance = CreateInstance(guid);
        instance.set3DAttributes(RuntimeUtils.To3DAttributes(position));
        instance.start();
        instance.release();
    }

The first method takes the string you provide as the path argument, i.e. event:/example, converts the string to a Guid and passes it to the second PlayOneShot method. There is where the actual playing takes place. There a new EventInstance is created, started and immediately released so it gets freed up from memory when the Event finishes playing. This is helpful for one-shot fire and forget sounds, so you don’t have to do these steps for each simple one shot sound.
Now back to your question: to play a one shot sound with a specific volume you can make use of method overloading in C#. In simple terms it means that methods can have the same name but with different parameters. To achieve this you can duplicate both methods and add a float parameter named volume to both methods like this:

    public static void PlayOneShot(string path, float volume, Vector3 position = new Vector3())
    {
        try
        {
            PlayOneShot(PathToGUID(path), volume, position);
        }
        catch (EventNotFoundException)
        {
            Debug.LogWarning("[FMOD] Event not found: " + path);
        }
    }

    public static void PlayOneShot(Guid guid, float volume, Vector3 position = new Vector3())
    {
        var instance = CreateInstance(guid);
        instance.set3DAttributes(RuntimeUtils.To3DAttributes(position));
        instance.setVolume(volume);
        instance.start();
        instance.release();
    }

We are adding EventInstance::setVolume to the second method before starting the instance, so the instance’s volume gets changed based on your volume argument. Now you can still call FMODUnity.RuntimeManager.PlayOneShot("event:/example"); for your usual sounds and pass a float variable when you need to control the volume of the one shot: FMODUnity.RuntimeManager.PlayOneShot("event:/example", 0.5f);.

1 Like

Thanks a lot.

That’s how I am goona do it ! :slight_smile:

… for some reason I did not thought about overriding / overloading the function. :sweat_smile:

1 Like