Change Event Instance Parameter from another script

Hi,

Trying to change a parameter value from an Event Instance created on another script, it seems that just providing the event path and setParameterByName doesn’t work. Is there a step I’m missing?

public override void OnEnter()
{
if (FMODEvent.Value == null || ParameterName.Value == null)
{
return;
}

var go = Fsm.GetOwnerDefaultTarget(GameObject);

Instance = RuntimeManager.CreateInstance(FMODEvent.Value);
RuntimeManager.AttachInstanceToGameObject(Instance, go.transform);

if (!EveryFrame)
{
    Instance.setParameterByName(ParameterName.Value, ParameterValue.Value);
    Finish();
}

}

Hi,

The issue is we are setting the parameter on an new instance on the one currently playing. We need to try a retrieve the one that was played via the other script.

If you know the path of the event etc: event:/Music/Level 01 we could use FMOD Engine | Studio Api System - Studio::System::Getevent to retrieve the FMOD Engine | Studio Api Eventdescription which we can use to get a list of all the created event instances: FMOD Engine | Studio Api Eventdescription - Studio::Eventdescription::Getinstancelist. This would then allow you to set the parameter on those instances. It would look something like this:

FMOD.RESULT result = FMODUnity.RuntimeManager.StudioSystem.getEvent(FMODEventPath, out FMOD.Studio.EventDescription eventDescription);

result = eventDescription.getInstanceCount(out int instanceCount);
FMOD.Studio.EventInstance[] instances = new FMOD.Studio.EventInstance[instanceCount];
result = eventDescription.getInstanceList(out instances);

foreach (FMOD.Studio.EventInstance currEvent in instances)
{
    result = currEvent.setParameterByName(ParameterName, ParameterValue);
}

Hope this helps!

1 Like

Wow thank you so much, that was exactly it!

I have another question though, since this loops through all of the events created with this path, I’m guessing this script would change the parameter on 2 events triggered by different objects?
In a co-op game, person A creates and plays the event and person B does so too, if I activate this script on person A it would change the parameter for both of them since it loops through all the created events right?

Correct, however we have solution for that too!

We can pass information to our instances with FMOD Engine | Studio Api Eventinstance - Studio::Eventinstance::Setuserdata, for example whether the instance is for player 1 or 2. The simplest way is to pass the player int directly to the instance (if using a emitter, it can be retrieved with: Unity Integration | Studioeventemitter::Eventinstance)

GCHandle playerHandle;
private int player = 1;

void Start()
{
    playerHandle = GCHandle.Alloc(player);

    instEvent = FMODUnity.RuntimeManager.CreateInstance(refEvent);

    FMOD.RESULT result = instEvent.setUserData(GCHandle.ToIntPtr(playerHandle));

    instEvent.start();
    instEvent.release();
}

private void OnDestroy()
{
    if (playerHandle.IsAllocated)
    {
        // Please make sure to free the handle or this will cause a memory leak! 
        playerHandle.Free();
    }
}

Then to check the player int is simple in our existing function!

foreach (FMOD.Studio.EventInstance currEvent in instances)
{
    IntPtr playerPtr;
    result = currEvent.getUserData(out playerPtr);

    GCHandle playerHandle = GCHandle.FromIntPtr(playerPtr);
    int player = (int)playerHandle.Target;
    if (player == 1)
    {
        result = currEvent.setParameterByName(ParameterName, ParameterValue);
    }
}

For another example of using setUserData have a look at our Unity Integration | Examples Programmer Sounds.

Hope this helps!

1 Like

Wow don’t think I’d had found this in the manual, I think this is exactly what I needed. Very much appreciated Connor, many thanks!

1 Like

No worries, if you have any more questions please do not hesitate to ask!

1 Like