Get timeline marker callbacks from referenced events

I’m implementing some rhythm-based mechanics where things happen in the game in response to timeline marker callbacks. The rhythmic pattern of callbacks is repetitive, and I want to contain all those markers in a referenced event for ease of comprehension and editing. However, it seems that Unity is no longer getting those marker callbacks when they are inside a referenced event. Is it possible to get these callbacks in Unity?

Which version of FMOD are you using?
We fixed an issue with marker callbacks not propagating from nested events in 2.00.11.

I’m using FMOD version 2.00.11 (and the associated Unity integration) and Unity 2019.3.15

I couldn’t tell from your image but are those markers two levels deep? I’ve just done a test here and timeline markers fire to callbacks for Events and Nested Events, just not any deeper than that. I’ve issued a task to have that fixed, it’s supposed to work for any level of nesting.

That’s only a single level of nesting - the timeline markers are in the event that the top-level event references. To be crystal clear: the first image is the top-level event, with references to the second event in the first layer (named “Markers”) and the second image is the full contents of said event. That’s what you mean by a single level of nesting, correct?

Thanks for looking into it! I’ll experiment some more and let you know if I figure anything out.

Yes, that certainly sounds like a single level of nesting and if you are on 2.00.11 that should be working. Is there any chance the libs you are using are from an older version?

I re-downloaded and -imported 2.00.11 unity integration - libs are all current - still no luck

Hey BadDreamGames

Can you confirm that you are registering the callback on the top level event, not on the nested event?

I’m calling EventInstance::setCallback on the top level event, is that what you mean?

_musicFmodCallback = new EVENT_CALLBACK(FMODEventCallback); _musicEventInstance.setCallback(_musicFmodCallback, EVENT_CALLBACK_TYPE.TIMELINE_BEAT | EVENT_CALLBACK_TYPE.TIMELINE_MARKER);

[AOT.MonoPInvokeCallback(typeof(EVENT_CALLBACK))] static FMOD.RESULT FMODEventCallback(EVENT_CALLBACK_TYPE type, EventInstance instance, IntPtr parameterPtr) { //... }

…where _musicEventInstance is the top-level event (1st image).

I’ve just done a quick proof of concept test in 2.00.11 and it’s working for me. Perhaps compare what I have here with your version.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CallbackTest : MonoBehaviour
{
    FMOD.Studio.EVENT_CALLBACK _musicFmodCallback;
    FMOD.Studio.EventInstance _musicEventInstance;


    [AOT.MonoPInvokeCallback(typeof(FMOD.Studio.EVENT_CALLBACK))]
    static FMOD.RESULT FMODEventCallback(FMOD.Studio.EVENT_CALLBACK_TYPE type, FMOD.Studio.EventInstance instance, System.IntPtr parameterPtr)
    {
        if (type == FMOD.Studio.EVENT_CALLBACK_TYPE.TIMELINE_MARKER)
        {
            var parameter = (FMOD.Studio.TIMELINE_MARKER_PROPERTIES)System.Runtime.InteropServices.Marshal.PtrToStructure(parameterPtr, typeof(FMOD.Studio.TIMELINE_MARKER_PROPERTIES));
            UnityEngine.Debug.LogFormat("Marker: {0}", (string)parameter.name);
        }

        return FMOD.RESULT.OK;
    }

    // Start is called before the first frame update
    void Start()
    {
        FMOD.Studio.EventDescription desc = FMODUnity.RuntimeManager.GetEventDescription("event:/Parent");
        desc.createInstance(out _musicEventInstance);
        
        _musicFmodCallback = new FMOD.Studio.EVENT_CALLBACK(FMODEventCallback);

        _musicEventInstance.setCallback(_musicFmodCallback, FMOD.Studio.EVENT_CALLBACK_TYPE.TIMELINE_BEAT | FMOD.Studio.EVENT_CALLBACK_TYPE.TIMELINE_MARKER);

        _musicEventInstance.start();
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

Hey Mathew & Tristan! After making some changes I got it working as expected, but to be honest I’m not quite sure where the issue was. I’ll post again when I pin-point the problem.