Using getLoadingState()

Hi. I need to check if a Bank called “Villages” is currently loaded. I managed to find some examples in the FMOD documentation but to me thoses are very hard to understand and I feel like I just need a concrete explanation to get the logic of how to actually implement those tools in my code.

Let’s take the following example :

RESULT Studio.Bank.getLoadingState(
out LOADING_STATE state
);

I struggle to understand what it would look like in a actual situation where I want to see the LoadingState in the Debug Log In Update().

Here’s some example code:

FMOD.Studio.LOADING_STATE loadingState;
FMOD.Studio.Bank villagesBank;
FMOD.RESULT result;

void Update()
{
    result = villagesBank.getLoadingState(out loadingState);
    if (loadingState == FMOD.Studio.LOADING_STATE.LOADED)
    {
        // Bank is loaded, do stuff here
    }
}

So here the function Studio.Bank.getLoadingState will return an FMOD_RESULT. If all goes well result will return FMOD_OK otherwise it will throw an error message, which you can read up on here.

The out parameter modifier will return the actual state of the bank to the loadingState variable, which you can then use however you need (such as checking if a bank has been loaded).

1 Like

Thank you so much Richard. With your example I was able to check my bank’s loading state very easily.

I found out that my bank was not loading as expected and I managed to find where it came from without really understanding why at first. If you think this would require to open a new topic just let me know and I will do so.

So what I want to do is load the “Villages” Bank and the “villageMusic” event when the player is entering the village’s sphere collider wich is set on “is trigger”. The collider is in the game object “Physics” which is a child of the game Object “Player”. Both are tagged as “Player”. In my editor, I have a game object called “TriggerBankAndMusic” (where my sphere collider is placed), a StudioBankLoader script and a StudioEventEmmiter script where my villageMusic event is assigned to. Both the scripts have their FMODEvent set to “trigger enter”. In my StudioBankLoader, I correctly declared the “Villages” Bank to be loaded on trigger enter whenever a collision tag “Player” is happening.

I found out that my StudioEventEmmiter “villageMusic” is called on trigger enter but not found, plus, the “Villages” Bank is not loaded. Obviously my tags are correctly set up, because the collision is properly detected by the StudioEventEmmiter script. So I searched on the OnTriggerEnter() function of my StudioBankLoader script and tried a bunch of different tag/layer conditions without success.

Finally I realized that my OnTriggerEnter() Function was embeded into an #if region :

#if UNITY_PHYSICS_EXIST || !UNITY_2019_1_OR_NEWER
void OnTriggerEnter(Collider other)
{
if (string.IsNullOrEmpty(CollisionTag) || other.CompareTag(CollisionTag))
{
HandleGameEvent(LoaderGameEvent.TriggerEnter);
print(“bankloaded”);
}
}
void OnTriggerExit(Collider other)
{
if (string.IsNullOrEmpty(CollisionTag) || other.CompareTag(CollisionTag))
{
HandleGameEvent(LoaderGameEvent.TriggerExit);
}
}
#endif

I tried to delete the region related lines and it simply worked. Tho, I don’t really get what I could do to fill the requirements of the region’s conditions, or even if I have to do so. Is it related to my Unity or FMOD integration version ? I am on Unity 2020.3.24f1 and FMOD 2.01.11.

I’ve tested using Unity 2020.3.30f1 and FMOD Studio 2.01.14 with no issues. Can you try updating the FMOD Unity integration to the latest release and see if that works?

Hi Richard. Sorry for the late response. I just updated the integration plugin to the 2.02.04 version. And here is the thing that I should have mention in my previous post. The script I am using to call the bank is a custom script wich is a duplicate of the StudioBankLoaderScript with minor changes. In this case I check the playback state of my music event in Update for the bank to wait until the event fades out before unloading.

Concerning my issue. The updated version of the integration plugin doesn’t change anything. I copy pasted the condition region from the new StudioBankLoader to my custom script and as soon as it checks if “UNITY_PHYSICS_EXIST”, I get the “[FMOD] Event not found” error.

Here is my script :

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

namespace FMODUnity
{
    [AddComponentMenu("FMOD Studio/Village Cut In Half Bank Loader")]
    public class VillageCutInHalfBankLoader : MonoBehaviour
    {
        public LoaderGameEvent LoadEvent;
        public LoaderGameEvent UnloadEvent;
        [BankRef]
        public List<string> Banks;
        public string CollisionTag;
        public bool PreloadSamples = false;
        private bool isQuitting;

        private StudioEventEmitter m_studioEventEmitter;
        private FMOD.Studio.EventInstance instance;

        void HandleGameEvent(LoaderGameEvent gameEvent)
        {
            if (LoadEvent == gameEvent)
            {
                Load();
            }
            if (UnloadEvent == gameEvent)
            {
                Unload();
            }
        }

        void Awake()
        {
            RuntimeUtils.EnforceLibraryOrder();
            HandleGameEvent(LoaderGameEvent.ObjectStart);
        }

        void OnApplicationQuit()
        {
            isQuitting = true;
        }

        void OnDestroy()
        {
            if (!isQuitting)
            {
                HandleGameEvent(LoaderGameEvent.ObjectDestroy);
            }
        }

// #if UNITY_PHYSICS_EXIST
        void OnTriggerEnter(Collider other)
        {
            if (string.IsNullOrEmpty(CollisionTag) || other.transform.root.tag == "Player")
            {
                HandleGameEvent(LoaderGameEvent.TriggerEnter);
            }
        }

        void OnTriggerExit(Collider other)
        {
            if (string.IsNullOrEmpty(CollisionTag) || other.transform.root.tag == "Player")
            {
                HandleGameEvent(LoaderGameEvent.TriggerExit);
            }
        }
// #endif

        void OnEnable()
        {
            HandleGameEvent(LoaderGameEvent.ObjectEnable);
        }

        void OnDisable()
        {
            HandleGameEvent(LoaderGameEvent.ObjectDisable);
        }

        public void Load()
        {
            foreach (var bankRef in Banks)
            {
                try
                {
                    RuntimeManager.LoadBank(bankRef, PreloadSamples);
                }
                catch (BankLoadException e)
                {
                    UnityEngine.Debug.LogException(e);
                }
            }
        }

        public void Unload()
        {
            foreach (var bankRef in Banks)
            {
                RuntimeManager.UnloadBank(bankRef);
            }
        }

        public void Start()
        {
          m_studioEventEmitter = GetComponent<StudioEventEmitter>();
        }

        public void Update()
        {
          instance = m_studioEventEmitter.EventInstance;

          FMOD.Studio.PLAYBACK_STATE PlaybackState(FMOD.Studio.EventInstance instance)
          {
            FMOD.Studio.PLAYBACK_STATE pS;
            instance.getPlaybackState(out pS);
            return pS;
          }
          // Debug.Log(PlaybackState(instance));

          if(PlaybackState(instance) == FMOD.Studio.PLAYBACK_STATE.STOPPED)
          {
            instance.clearHandle();
            Unload();
          }
        }
    }
}

And a screenshot of my gameobject’s components :

I have a feeling this is a race condition issue. It could be the event emitter is trying to play the event before the bank has finished loading. It’s possible that the UNITY_PHYSICS_EXIST check is what is playing a part in whether the bank is loaded first or the event is (attempted) to play.

Are you able to disable the event emitter component and instead use the Update() function in your VillageCutInHalfBankLoader script to play the event when the trigger is met? This should rule out if the bank is being loaded before the event is played.

I tried to call the event when the trigger is met directly from a new eventref in the script but it doesn’t change the situation. I wanted to see what would happen if I load the bank on Init, and I found that even if the bank is already loaded. The Events are not found (even the ambiance event that are called later after the bank trigger) while there is a specified bank in the bankLoaderScript. If I leave the bankRef empty, everything that is embeded into the UNITY_PHYSICS_EXIST is played.

That is very strange. For now, please leave the UNITY_PHYSICS_EXIST check deleted since it helps with the situation and I will pass this onto our Unity integration team to investigate for a future release. It doesn’t seem to affect my machine but I will pass it on in case they can dig deeper into what is happening.

1 Like

An integrations developer has taken a look into this and this is their suspicion:

This is probably because the user is copying the StudioBankLoader source into a different assembly, where UNITY_PHYSICS_EXIST and UNITY_PHYSICS2D_EXIST haven’t been defined. They should either inherit from BankLoader, make their script inside the FMODUnity assembly, or copy the UNITY_PHYSICS_EXISTS definitions into their own assembly.