Trigger code after studioeventemitter has finished playing event instance

Hi,

I’m having an issue for something that seems like it should be basic.

I have a bunch of StudioEventEmitters in my Unity project (version 6000.0.25f1)

These get triggered using ‘Trigger Enter’ under the Event Play Trigger and get stopped with Event Stop Trigger set to ‘Trigger Exit’

This is all working, sound is coming through, starting and stopping when it should.

I have made a script that has a reference to a list of Studio Event Emitters.

When my list of Studio Event Emitters have all played at least once, I want to trigger another function to show the credits (i.e. TriggerCredits() )

However, I for the life of me can’t seem to register a callback or some sort of way to get an event/notified/triggered when these events stop.

I can show what I have done so far, but ideally I’d like to hear how this is meant to set up as I’m a bit new to FMOD. From what I understand, each StudioEventEmitter creates an EventInstance WHEN it plays the event, so where to I register a callback or some sort of event to trigger when that instance is finished, if I don’t know when it is triggered?

Any advice is appreciated, along with if I should add a helper script to the game objects that have the StudioEventEmitter component so I can control all the instances each StudioEventEmitter has and their status.

I am able to Start and Stop some of them through code, but we work with an audio person so I’d like them to be able to use the StudioEventEmitter component as I’m not confident enough to replace it with my own custom one. I would love any examples and explanation as FMOD is such a great tool I want to learn, but am finding difficult to use as a developer.

Thanks very much!

1 Like

Hi,

I have made a script that will apply a callback to an emitter event instance once it starts playing and then log Event Stopped once it has stopped:

Example Script
public class Example : MonoBehaviour
{
    [SerializeField] private FMODUnity.StudioEventEmitter emitter;
    private FMOD.Studio.EVENT_CALLBACK emitterCallback;
    bool applied = false;

    // Start is called before the first frame update
    void Start()
    {
        emitterCallback = new FMOD.Studio.EVENT_CALLBACK(EmitterCallback);
    }

    // Update is called once per frame
    void Update()
    {
        if (!applied)
        {
            if (emitter.EventInstance.getPlaybackState(out FMOD.Studio.PLAYBACK_STATE state) == FMOD.RESULT.OK)
            {
                if (state == FMOD.Studio.PLAYBACK_STATE.STARTING)
                {
                    emitter.EventInstance.setCallback(emitterCallback, FMOD.Studio.EVENT_CALLBACK_TYPE.ALL);
                    Debug.Log("Applied callback");
                    applied = true;
                }
            }
        }
    }

    [AOT.MonoPInvokeCallback(typeof(FMOD.Studio.EVENT_CALLBACK))]
    static FMOD.RESULT EmitterCallback(FMOD.Studio.EVENT_CALLBACK_TYPE type, IntPtr instancePtr, IntPtr parameterPtr)
    {
        if (type == FMOD.Studio.EVENT_CALLBACK_TYPE.STOPPED)
        {
            Debug.Log("Event stopped");
        }
        return FMOD.RESULT.OK;
    }
}

The issue you have have encountered is the instance is not valid until it is played. Fortunately, we can assign the callback after the fact. This is a very basic implementation please let me know if I can assist further!

I will make a task to investigate options to improve this workflow. Thank you for bringing this to our attention!