[Beginner] How do I check, if an event instance is assigned a specific event reference?

Hello everyone!

I started learning Unity and FMOD for a work project a few weeks ago and have now gotten to a problem, that a tutorial or Google search couldn’t solve:

In my code, I want to check, if my EventInstance called “Audio” is set to a specific value / assigned to a specific Event.

Essentially I want to play a certain sound event for different distances between the sound source and the player (in 3D). So my plan was to create an EventInstance in the Start() function as a default event that plays when the game starts. Then it checks in the FixedUpdate() function, if the player is in a certain distance (%) on the way to the object.
If that is the case it’s supposed to check if the corresponding event is not playing and if that’s the case, it should destroy the previous EventInstance and create a new one under the same name (Audio), playing the correct event instead.
I tried the standard C#: if (Audio != “EventReferenceName”) which doesn’t seem to work.

Here is my code:
(ignore the occlusion and linecasting stuff, I took a script from Scott Game Sounds as a basis and that part works without any issues)

using UnityEngine;
using FMODUnity;
using FMOD.Studio;

public class FirstPersonOcclusion : MonoBehaviour
{
    [Header("FMOD Event")]
    [SerializeField]
    private EventReference Ueber75;
    [SerializeField]
    private EventReference Audio75;
    [SerializeField]
    private EventReference Audio50;
    [SerializeField]
    private EventReference Audio25;
    [SerializeField]
    private EventReference Audio5;
    private EventInstance Audio;
    private EventDescription AudioDes;
    private StudioListener Listener;
    private PLAYBACK_STATE pb;

    [Header("Occlusion Options")]
    [SerializeField]
    [Range(0f, 10f)]
    private float SoundOcclusionWidening = 1f;
    [SerializeField]
    [Range(0f, 10f)]
    private float PlayerOcclusionWidening = 1f;
    [SerializeField]
    private LayerMask OcclusionLayer;

    private bool AudioIsVirtual;
    private float MaxDistance;
    private float ListenerDistance;
    private float StartDistance;
    private float lineCastHitCount = 0f;
    private Color colour;

    private void Start()
    {
        Audio = RuntimeManager.CreateInstance(Ueber75);
        RuntimeManager.AttachInstanceToGameObject(Audio, GetComponent<Transform>(), GetComponent<Rigidbody>());
        Audio.start();
        Audio.release();

        AudioDes = RuntimeManager.GetEventDescription(Ueber75);
        AudioDes.getMinMaxDistance(out float MinDistance, out MaxDistance);

        Listener = FindObjectOfType<StudioListener>();

        Vector3 StartingPosition = new Vector3(Listener.transform.position.x, Listener.transform.position.y, Listener.transform.position.z);
        StartDistance = Vector3.Distance(StartingPosition, transform.position);
    }

    private void FixedUpdate()
    {
        Audio.isVirtual(out AudioIsVirtual);
        Audio.getPlaybackState(out pb);
        ListenerDistance = Vector3.Distance(transform.position, Listener.transform.position);

        if (!AudioIsVirtual && pb == PLAYBACK_STATE.PLAYING)
            OccludeBetween(transform.position, Listener.transform.position);

        lineCastHitCount = 0f;

        if (ListenerDistance <= (StartDistance / 100 * 75) && ListenerDistance > (StartDistance / 100 * 50))
        {
            if (//Check here if EventInstance "Audio" has NOT the value "Audio75")
            {
                Audio.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
                Audio = RuntimeManager.CreateInstance(Audio75);
                RuntimeManager.AttachInstanceToGameObject(Audio, GetComponent<Transform>(), GetComponent<Rigidbody>());
                Audio.start();
                Audio.release();

                AudioDes = RuntimeManager.GetEventDescription(Audio75);
            }
        }

Maybe you can also tell me if something else should be changed. For example I also am not sure if the previous EventInstance actually gets properly destroyed here; or maybe I have to make a new variable for every specific distance too(?).

Anyways, thanks for your patience!

After asking ChatGPT for an hour, I finally got a working solution for my problem. I still don’t 100% know why exactly it works or what it does, but I will try to find that out. The working code is:

if (ListenerDistance <= (StartDistance / 100 * 75) && ListenerDistance > (StartDistance / 100 * 50))
        {
            EventDescription audio75Des = RuntimeManager.GetEventDescription(Audio75);

            if (AudioDes.isValid() && AudioDes.handle != audio75Des.handle)
            {
                Audio.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
                Audio = RuntimeManager.CreateInstance(Audio75);
                RuntimeManager.AttachInstanceToGameObject(Audio, GetComponent<Transform>(), GetComponent<Rigidbody>());
                Audio.start();
                Audio.release();

                AudioDes = RuntimeManager.GetEventDescription(Audio75);
            }

The thing that makes me question is the lower case “a” in “audio75Des.handle”, because usually all the variables in the code start with a capital A. Is this a new variable? The “EventDescription” and .handle stuff is still a little confusing for me.

Hi,

There are a couple of options for checking event description identities. either EventDescription::getID() or EventDesctription::getPath() (FMOD API | Studio API Reference - Studio::EventDescription) but checking the .handle is valid too.

Yes, as you are calling release() on the event before you are reassigning it means it should be cleaned up by the FMOD system after you call Audio.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);. I would suggest maybe checking !Audio.isValid() before assigning it to the new event just to be safe.

I will also link to our Unity Scripting Examples which have lots of examples using our API with Unity which might be a useful reference: Unity Integration | Scripting Examples.

If you have any more questions please do not hesitate to ask!