Studio Event Emitter (Sound by Distance) does not work

Hello everyone,


I want to implement a Sound by Distance. It had worked at some point but now, after tons of hours, it doesn’t anymore. No matter how close I am to the object, no sound appears. What information do you need to find out where the problem might lies? I sadly only have very basic knowledge yet. I would be more than glad for any response!

Can you elaborate on what exactly you mean by “sound by distance”? Do you mean:

  • You want to attenuate the volume of an event based on distance from the event
  • You want to start/stop an event based on distance from the event
  • You want to change an event or global parameter based on distance from the event

Or something else entirely?

Sure! I think it’s your first point. What I’m trying to achieve is to connect a sound with the Studio Event Emitter to any object, so as soon as I approach the respective object/event with the player, the sound will get louder. It should reduce the volume of that sound if I move away. The volume during the movement should depend on the two custom radii. I created a spatializer for the audio track in the FMOD Studio event I want to use. Like stereo/surround but in 2D.
I also have a Studio Listener attached to the Main Camera.
Some audio commands for SFX like footseps are also based in the player movement script.

Here’s my AudioManager script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FMODUnity;
using FMOD.Studio;
using System.Runtime.InteropServices.WindowsRuntime;

public class AudioManager : MonoBehaviour
{
[Header(“Volume”)]
[Range(0, 1)]
public float MasterVolume = 1;
[Range(0, 1)]
public float MusicVolume = 1;
[Range(0, 1)]
public float AmbienceVolume = 1;
[Range(0, 1)]
public float SFXVolume = 1;

private Bus MasterBus;
private Bus MusicBus;
private Bus AmbienceBus;
private Bus SFXBus;

private List<EventInstance> eventInstances;
//private List<StudioEventEmitter> eventEmitters;
private EventInstance AmbienceEventInstance;
private EventInstance MusicEventInstance;
public static AudioManager instance { get; private set; }

private EventInstance StartMelody;

PauseMenu pauseMenu;

private void Awake()
{
    if (instance != null)
    {
        Debug.LogError("Found more than one Audio Manager in the scene.");
    }
    instance = this;

    eventInstances = new List<EventInstance>();
    //eventEmitters = new List<StudioEventEmitter>();

    MasterBus = RuntimeManager.GetBus("bus:/");
    MusicBus = RuntimeManager.GetBus("bus:/Music");
    AmbienceBus = RuntimeManager.GetBus("bus:/Ambience");
    SFXBus = RuntimeManager.GetBus("bus:/SFX");
}

private void Start()
{
    InitializeAmbience(FMODEvents.instance.ForestScatterer);
    set3DAttrib(AmbienceEventInstance);
    InitializeMusic(FMODEvents.instance.ForestMelody);
    PauseMenu refScript = GetComponent<PauseMenu>();
    pauseMenu = GetComponent<PauseMenu>();

    StartMelody = AudioManager.instance.CreateInstance(FMODEvents.instance.StartMelody);
    StartMelody.start();
}

private void Update()
{
    MasterBus.setVolume(MasterVolume);
    MusicBus.setVolume(MusicVolume);
    AmbienceBus.setVolume(AmbienceVolume);
    SFXBus.setVolume(SFXVolume);

    if (PauseMenu.isPaused == true)
    {
        MasterVolume = 0.3f;
    }
    else
    {
        MasterVolume = 1;
    }

}

private void InitializeAmbience(EventReference AmbienceEventReference)
{
    AmbienceEventInstance = CreateInstance(AmbienceEventReference);
    AmbienceEventInstance.start();
}

private void InitializeMusic(EventReference MusicEventReference)
{
    MusicEventInstance = CreateInstance(MusicEventReference);
    MusicEventInstance.start();
}

public void SetAmbienceParameter(string parameterName, float parameterValue)
{
    AmbienceEventInstance.setParameterByName(parameterName, parameterValue);
}
public void SetAmbienceParameter1(string parameterName1, float parameterValue1)
{
    AmbienceEventInstance.setParameterByName(parameterName1, parameterValue1);
}

public void SetMusicArea(MusicArea area)
{
    MusicEventInstance.setParameterByName("area", (float)area);
}

public void PlayOneShot(EventReference sound, Vector3 worldPos)
{
    RuntimeManager.PlayOneShot(sound, worldPos);
}

public EventInstance CreateInstance(EventReference eventReference)
{
    EventInstance eventInstance = RuntimeManager.CreateInstance(eventReference);
    eventInstances.Add(eventInstance);
    return eventInstance;
}

/*public StudioEventEmitter InitializeEventEmitter(EventReference eventReference, GameObject emitterGameObject)
{
    StudioEventEmitter emitter = emitterGameObject.GetComponent<StudioEventEmitter>();
    emitter.EventReference = eventReference;
    eventEmitters.Add(emitter);
    return emitter;
}*/

void set3DAttrib(EventInstance inst)
{
    Vector3 position = transform.position;
    FMOD.ATTRIBUTES_3D attributes = new FMOD.ATTRIBUTES_3D
    {
        position = RuntimeUtils.ToFMODVector(position),
        forward = RuntimeUtils.ToFMODVector(transform.forward),
        up = RuntimeUtils.ToFMODVector(transform.up),
        velocity = new FMOD.VECTOR { x = 0, y = 0, z = 0 }
    };

    // 3D-Attribute setzen
    inst.set3DAttributes(attributes);
}
private void CleanUp()
{
    // stop and release any created instances
    foreach (EventInstance eventInstance in eventInstances)
    {
        eventInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
        eventInstance.release();
    }
    // stop all of the event emitters, because if we don't they may hang around in other scenes
    /*foreach (StudioEventEmitter emitter in eventEmitters)
    {
        emitter.Stop();
    }*/
}

private void OnDestroy()
{
    CleanUp();
}

}

This can be set up entirely within FMOD Studio, without any additional code in Unity for calculating distances or adjusting volume.

You’ll want to add an FMOD Spatializer to your event’s master track, as you’ve likely already done, then set the “Envelopment” setting to “User” and increase the “Minimum Extent” to its maximum setting of 360 degrees.

envelopment

Essentially, this makes sure that your event’s audio stays 2D, but is still attenuated based on the distance from your listener. You can tweak the minimum and maximum distances for the attenuation by adjusting the Min & Max distance event macro, which is located in the bottom right hand corner of the event editor when the event’s master track is selected:

You already have a listener on your camera, so if you play this event using an event emitter component, the event will automatically be “attached” to the component’s GameObject, and the 2D attenuation based on distance from the listener should be handled automatically.

If I’ve misunderstood the audio behavior you’re going for, or if you run into an issue getting it working, feel free to let me know.

Oh my god, thank you so much!!! Apparently the mistake was to attach the Spatializer to the master track, not to the audio track that contains the audio I want to play. Because my master track is empty and I only have one audio track in this event, so I attached it to that one. What a detail, I was already starting to get desperate.

1 Like