How to load multiple .bank files created by multiple users at runtime without using the Master.strings.bank file?

Hello,

I am working on a racing game project using Unity3D engine.

My project uses FMOD for the car engine sound.
In addition, there is support for modding the car’s engine sound from the user side.
For example, in the game’s installation directory, there is a directory called cars/sounds. And the user can create a folder for each vehicle and put the car’s engine sound into each vehicle’s folder respectively.
The condition is that all files .bank and .strings.bank generated must contain the same events like: event:/engine_ext or event:/engine_int.
The problem here is that because the .bank files are created by different users, we will not be able to use the same Master.strings.bank file to manage them.
Each .bank file created by the user will have a corresponding .strings.bank file. For example audi.bank & audi.strings.bank or i20.bank & i20.strings.bank.
The problem here is that FMOD unity doesn’t seem to support loading each bank file separately, and a Master.strings.bank file is required.
I would like to ask is there a way to load the each bank file separately at runtime? Or is this not possible?
If yes, can you help me how to do it? Including changing the source code in the FMOD unity plugin.

Or at least FMOD Unity has support for loading multiple .bank files at once (without using Master.strings.bank)? If possible but need to modify the source code , how can I do ?

Because the .bank file is user generated, we cannot use it this way.
https://fmod.com/resources/documentation-studio?version=2.0&page=supporting-downloadable-and-user-generated-content.html

(Which we want to do is like the game Assetto Corsa)

Thank you very much.

1 Like

I’ve implemented like this. Can someone check for me if there are any problems with this ?
This method has a disadvantage that I can only load a single bank at a time.
For example, A.bank is loaded, B.bank can not loaded at the same time.

FMOD Settings
At Initialization, set Load Banks = None

To load banks at runtime, I will do like this:
Scripts:

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

public class FMODTest : MonoBehaviour
{
    public string bankName = "";
    public Slider throttleSlider;
    public Slider rpmSlider;
    public FMODUnity.StudioEventEmitter emitter;

    private GameObject engineEmitterObject;

    void OnEnable()
    {
        FMODUnity.RuntimeManager.LoadBank(bankName, true);
        FMODUnity.RuntimeManager.LoadBank(bankName + ".strings", true);

        FMOD.Studio.Bank[] bankList;
        FMODUnity.RuntimeManager.StudioSystem.getBankList(out bankList);
        FMOD.GUID guid = FMOD.GUID.Parse("0fa5735c-624d-40ae-9606-d79616137c5d");
        foreach (FMOD.Studio.Bank b in bankList)
        {
            string path;
            b.getPath(out path);

            FMOD.Studio.EventDescription[] eventDescs;
            b.getEventList(out eventDescs);
            foreach (var e in eventDescs)
            {
                e.getPath(out string ePath);
                e.getID(out FMOD.GUID guid1);
                if (ePath == "event:/engine_ext")
                {
                    guid = guid1;
                }
            }

        }

        engineEmitterObject = new GameObject();
        engineEmitterObject.transform.SetParent(transform);
        engineEmitterObject.transform.localPosition = Vector3.zero;
        engineEmitterObject.transform.localRotation = Quaternion.identity;

        emitter = engineEmitterObject.AddComponent<FMODUnity.StudioEventEmitter>();
        emitter.EventReference.Guid = guid;
        emitter.PlayEvent = FMODUnity.EmitterGameEvent.ObjectStart;
        emitter.StopEvent = FMODUnity.EmitterGameEvent.ObjectDestroy;
    }

    private void OnDestroy()
    {
        FMODUnity.RuntimeManager.UnloadBank(bankName);
        FMODUnity.RuntimeManager.UnloadBank(bankName + ".strings");
        DestroyImmediate(emitter);
        DestroyImmediate(engineEmitterObject);
    }

    private void OnDisable()
    {
        FMODUnity.RuntimeManager.UnloadBank(bankName);
        FMODUnity.RuntimeManager.UnloadBank(bankName + ".strings");
        emitter = null;
        DestroyImmediate(emitter);
        DestroyImmediate(engineEmitterObject);
    }

    void Update()
    {
        if (emitter == null)
            return;

        float throttle = throttleSlider.value;
        float rpms = rpmSlider.value;

        emitter.SetParameter("throttle", throttle);
        emitter.SetParameter("rpms", rpms);
    }
}

Hi, sorry for the delayed response.

Your code seems fine - the key thing is that you seem to have grasped how to load and unload banks from script.

It’s worth noting that a master bank does not have to be “Master.bank” specifically, the banks just needs to be marked as the master bank in FMOD Studio. Ultimately, you do need to have the master bank and master strings bank for each of your separately created banks loaded at runtime in order to get your setup to work, as the master bank contains all the event metadata and mixer structure for the project. However, as the docs on Loading DLC and UGC Banks state,

If you load one or more UGC or DLC master banks after loading the game’s existing master bank, the additional buses in the DLC or UGC master banks are automatically appended to the existing routing hierarchy.

In the case that you want to load multiple UGC banks simultaneously, as long as you’re loading your main project’s master banks first, and then the UGC master banks afterwards, it should work fine. The main issue in your case is probably that the UGC events are sharing names with existing events - you will likely run into issues if you load two banks that contain the same event/mixer paths or GUIDs, etc.

Hope this helps!