I’m trying to build our game on iOS for the first time since adding FMOD and am getting an error that says:
The script ‘Audio.FMODSound’ could not be instantiated!
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using FMOD.Studio;
using FMODUnity;
using PixelCrushers.DialogueSystem;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
namespace Audio
{
    public class FMODSound : Sound
    {
        // Constants
        private const float GarbageCollectorIntervalSecs = 1f;
        private static readonly WaitForSeconds GarbageCollectorIntervalWait = new WaitForSeconds(GarbageCollectorIntervalSecs);
        private static readonly FMOD.Sound NullSoundStruct; // zeroed out
        private static readonly FMOD.Studio.SOUND_INFO NullSoundInfoStruct; // zeroed out
        private static readonly FMOD.Studio.EventInstance NullEventInstance; // zeroed out
        private static readonly SoundInstance NullSoundInstance = new FMODSoundInstanceContainer().GetReference();
        // References
        // [FMODUnity.BankRef]
        // public List<string> GlobalBanks;
        // [FMODUnity.BankRef]
        // public List<string> LocalizedGlobalBanks;
        // [FMODUnity.EventRef]
        public const string DialogueEvent = "event:/Voice/Dialogue";
        // Properties
        private List<FMODSoundInstanceContainer> ActiveSoundInstances;
        private Dictionary<string, string> LoadedBanksToOwner;
        private SoundInstance CurrentMusic;
        private Coroutine GarbageCollectorCoroutine;
        // #if UNITY_EDITOR
        //         void OnValidate()
        //         {
        //             for (int i = 0; i < LocalizedGlobalBanks.Count; i++)
        //             {
        //                 if (LocalizedGlobalBanks[i].Contains("_")) LocalizedGlobalBanks[i] = LocalizedGlobalBanks[i].Split('_')[0];
        //             }
        //         }
        // #endif
        // protected void Start() => StartCoroutine(EnableMeteringRoutine());
        // private IEnumerator EnableMeteringRoutine()
        // {
        //     // Wait for Initialization
        //     yield return new WaitUntil(() => FMODUnity.RuntimeManager.IsInitialized);
        //     FMOD.Studio.Bus bus = FMODUnity.RuntimeManager.GetBus("bus:/Voice");
        //     FMOD.RESULT result = bus.lockChannelGroup(); // Forces bus to be created
        //     if (result != FMOD.RESULT.OK)
        //     {
        //         Debug.LogError($"Failed to create bus to enable metering {result}");
        //         yield break;
        //     }
        //     // Channel group won't be created when FMOD is in async mode until  
        //     // the command has been executed in the async thread.  So we just keep
        //     // trying to fetch the group until it exists.  We only try 1000 times though.
        //     int safetyValve = 1000;
        //     FMOD.ChannelGroup channelGroup;
        //     channelGroup.handle = IntPtr.Zero;
        //     yield return new WaitUntil(() =>
        //     {
        //         safetyValve--;
        //         if (--safetyValve <= 0 || (result = bus.getChannelGroup(out channelGroup)) == FMOD.RESULT.OK) return true;
        //         return false;
        //     });
        //     if (result != FMOD.RESULT.OK)
        //     {
        //         Debug.LogError($"Failed to fetch channel group to enable metering for voice {result}");
        //         bus.unlockChannelGroup();
        //         yield break;
        //     }
        //     FMOD.DSP dsp;
        //     if (channelGroup.getDSP(0, out dsp) != FMOD.RESULT.OK)
        //     {
        //         Debug.LogError($"Failed to fetch dsp to enable metering for voice {result}");
        //         bus.unlockChannelGroup();
        //         yield break;
        //     }
        //     dsp.setMeteringEnabled(false, true);
        //     bus.unlockChannelGroup();
        // }
        protected override void OnEnable()
        {
            // Base
            base.OnEnable();
            // Create Loaded Banks Map
            LoadedBanksToOwner = new Dictionary<string, string>();
            // Create Sound Instance List
            ActiveSoundInstances = new List<FMODSoundInstanceContainer>();
            // Load Global Banks 
            // foreach (string bank in GlobalBanks) LoadBank(bank);
            LoadBank("Master");
            LoadBank("Master.strings");
            LoadBank("Global Events");
            // Load Localized Global Banks 
            // foreach (string bank in LocalizedGlobalBanks) LoadBankLocalized(bank);
            LoadBankLocalized("Common - Dialogue");
            LoadBankLocalized("Inventory - Dialogue");
            // Start Garbage Collector
            GarbageCollectorCoroutine = StartCoroutine(GarbageCollectorRoutine());
        }
        protected override void OnDisable()
        {
            // Stop Garbage Collector
            StopCoroutine(GarbageCollectorCoroutine);
            // Force Garbage Collect All
            RunGarbageCollectorSweep(true);
            // Unload All Banks
            UnloadAllBanks();
        }
        /**
         * Bank Loading
         */
        protected override void HandleLoadBankLocalized(string bank) => HandleLoadBank(bank + "_" + Localization.Language);
        protected override void HandleLoadBank(string bank)
        {
            if (!LoadedBanksToOwner.ContainsKey(bank))
            {
                try
                {
                    FMODUnity.RuntimeManager.LoadBank(bank);
                }
                catch (BankLoadException e)
                {
                    Debug.LogError("Failed to load bank: " + e);
                }
            }
            if (SceneManager.GetActiveScene() == null)
            {
                UnityAction<Scene, Scene> handler = null;
                SceneManager.activeSceneChanged += handler = (Scene from, Scene to) =>
                {
                    SceneManager.activeSceneChanged -= handler;
                    LoadedBanksToOwner[bank] = SceneManager.GetActiveScene().name;
                };
            }
            else LoadedBanksToOwner[bank] = SceneManager.GetActiveScene().name;
        }
        protected override void HandleUnloadBank(string bank)
        {
            if (string.IsNullOrEmpty(bank) || !LoadedBanksToOwner.ContainsKey(bank)) return;
            LoadedBanksToOwner.Remove(bank);
            FMODUnity.RuntimeManager.UnloadBank(bank);
        }
        private void UnloadAllBanks()
        {
            string[] banks = new string[LoadedBanksToOwner.Count];
            LoadedBanksToOwner.Keys.CopyTo(banks, 0);
            foreach (string bank in banks) UnloadBank(bank);
        }
        /**
         * Sound Playing
         */
        protected override SoundInstance HandleCreateSound(string soundEventKey) => CreateSoundInstance(soundEventKey).GetReference();
        protected override SoundInstance HandleCreateMusic(string musicEventKey)
        {
            // Stop Old Music
            if (CurrentMusic != null) CurrentMusic.Stop();
            // Return Sound Instance
            CurrentMusic = CreateSoundInstance(musicEventKey).GetReference();
            CurrentMusic.Start();
            return CurrentMusic;
        }
        protected override void HandlePlayOneShot(string soundEventKey) => FMODUnity.RuntimeManager.PlayOneShot(soundEventKey, Vector3.zero);
        protected override void HandleCreateDialogueRoutineAsync(string dialogueTableKey, Action<SoundInstance> soundReadyCallback)
        {
            if (soundReadyCallback == null) return;
            StartCoroutine(HandlePlayDialogueRoutineAsyncRoutine(dialogueTableKey, soundReadyCallback));
        }
        private IEnumerator HandlePlayDialogueRoutineAsyncRoutine(string dialogueTableKey, Action<SoundInstance> soundReadyCallback)
        {
            // Load Sound Path
            FMOD.Studio.SOUND_INFO dialogueSoundInfo;
            FMOD.RESULT keyResult = FMODUnity.RuntimeManager
                .StudioSystem
                .getSoundInfo(dialogueTableKey, out dialogueSoundInfo);
            if (keyResult != FMOD.RESULT.OK)
            {
                Debug.LogError("Couldn't find dialogue with key: " + dialogueTableKey);
                soundReadyCallback?.Invoke(NullSoundInstance);
                yield break;
            }
            // Load Sound
            FMOD.Sound dialogueSound;
            FMOD.MODE soundMode = FMOD.MODE.LOOP_NORMAL
                | FMOD.MODE.CREATECOMPRESSEDSAMPLE
                | FMOD.MODE.NONBLOCKING;
            FMOD.RESULT soundResult = FMODUnity.RuntimeManager.CoreSystem.createSound(
                dialogueSoundInfo.name_or_data, soundMode | dialogueSoundInfo.mode,
                ref dialogueSoundInfo.exinfo, out dialogueSound);
            if (soundResult != FMOD.RESULT.OK)
            {
                Debug.LogError("Couldn't load sound: " + dialogueTableKey);
                soundReadyCallback?.Invoke(NullSoundInstance);
                yield break;
            }
            // Wait to Load
            int maxFrameWait = 120;
            FMOD.OPENSTATE openstate;
            uint percentbuffered;
            bool starving;
            bool diskbusy;
            dialogueSound.getOpenState(out openstate, out percentbuffered, out starving, out diskbusy);
            while (openstate != FMOD.OPENSTATE.READY)
            {
                yield return null;
                dialogueSound.getOpenState(out openstate, out percentbuffered, out starving, out diskbusy);
                if (--maxFrameWait <= 0)
                {
                    dialogueSound.release();
                    Debug.LogError("Failed to load dialogue sound " + dialogueTableKey);
                    soundReadyCallback?.Invoke(NullSoundInstance);
                    yield break;
                }
            }
            // Create Instance 
            FMODSoundInstanceContainer soundInstanceContainer = CreateSoundInstance(DialogueEvent, dialogueSound, dialogueSoundInfo);
            // Enable Metering
            // Debug.Log("WHAT THE FUCK FMOD: https://qa.fmod.com/t/err-studio-not-loaded-cant-enable-metering/17358");
            // yield return null;
            // yield return null;
            // yield return null;
            // yield return null;
            // yield return null;
            // yield return null;
            // FMOD.ChannelGroup channelGroup;
            // FMOD.RESULT result = soundInstanceContainer.EventInstance.getChannelGroup(out channelGroup);
            // if (result != FMOD.RESULT.OK)
            // {
            //     Debug.LogError($"Failed to fetch channel group to enable metering for voice {result}");
            // }
            // FMOD.DSP dsp;
            // if (channelGroup.getDSP(0, out dsp) != FMOD.RESULT.OK)
            // {
            //     Debug.LogError($"Failed to fetch dsp to enable metering for voice {result}");
            // }
            // dsp.setMeteringEnabled(false, true);
            // Return the instance
            soundReadyCallback(soundInstanceContainer.GetReference());
        }
        protected override SoundInstance HandleGetCurrentMusic() => CurrentMusic;
        /**
         * Timescale Pause Toggle
         */
        protected override void HandleTimescalePauseToggle(bool pause)
        {
            foreach (FMODSoundInstanceContainer instanceContainer in ActiveSoundInstances)
            {
                instanceContainer.TimeScalePause(pause);
            }
        }
        private FMODSoundInstanceContainer CreateSoundInstance(string eventName) => CreateSoundInstance(eventName, NullSoundStruct, NullSoundInfoStruct);
        private FMODSoundInstanceContainer CreateSoundInstance(string eventName, FMOD.Sound sound, FMOD.Studio.SOUND_INFO soundInfo)
        {
            FMOD.Studio.EventInstance instance = FMODUnity.RuntimeManager.CreateInstance(eventName);
            FMODSoundInstanceContainer instanceContainer = new FMODSoundInstanceContainer(instance, eventName, sound, soundInfo);
            ActiveSoundInstances.Add(instanceContainer);
            return instanceContainer;
        }
        private IEnumerator GarbageCollectorRoutine()
        {
            while (true)
            {
                yield return GarbageCollectorIntervalWait;
                RunGarbageCollectorSweep();
            }
        }
        private void RunGarbageCollectorSweep(bool destroyAll = false)
        {
            List<FMODSoundInstanceContainer> retainList = new List<FMODSoundInstanceContainer>();
            FMOD.Studio.PLAYBACK_STATE state;
            foreach (FMODSoundInstanceContainer container in ActiveSoundInstances)
            {
                // Destroy Everything
                if (destroyAll)
                {
                    container.DestroyInstance();
                    continue;
                }
                // Conditional Destruction 
                // Must be Stopped/Paused and Dead
                if (!container.IsAlive())
                {
                    bool isPaused;
                    container.EventInstance.getPaused(out isPaused);
                    container.EventInstance.getPlaybackState(out state);
                    if (state == FMOD.Studio.PLAYBACK_STATE.STOPPED || isPaused)
                    {
                        container.DestroyInstance();
                    }
                }
                else retainList.Add(container);
            }
            ActiveSoundInstances = retainList;
        }
        /**
         * Sound Instance Classes
         */
        private class FMODSoundInstanceContainer
        {
            // Parent Class Public
            public FMOD.Studio.EventInstance EventInstance;
            public string EventKey;
            public List<CallbackAndMask> Callbacks;
            // Properties
            private FMOD.Studio.EVENT_CALLBACK FMODCallback;
            private WeakReference<FMODSoundInstance> Reference;
            private FMODCallbackWrapper CallbackWrapper;
            private GCHandle CallbackWrapperHandle;
            private bool timeScalePaused;
            public FMODSoundInstanceContainer() : this(NullEventInstance, string.Empty) { } // Used for failure to load
            public FMODSoundInstanceContainer(FMOD.Studio.EventInstance eventInstance, string eventKey) : this(eventInstance, eventKey, NullSoundStruct, NullSoundInfoStruct) { }
            public FMODSoundInstanceContainer(FMOD.Studio.EventInstance eventInstance, string eventKey, FMOD.Sound sound, FMOD.Studio.SOUND_INFO soundInfo)
            {
                this.EventInstance = eventInstance;
                this.EventKey = eventKey;
                this.Reference = new WeakReference<FMODSoundInstance>(new FMODSoundInstance(this));
                this.Callbacks = new List<CallbackAndMask>(128);
                // Setup Callback Handler
                this.FMODCallback = new FMOD.Studio.EVENT_CALLBACK(FMODUnmanagedCallback);
                this.CallbackWrapper = new FMODCallbackWrapper(FMODCallbackHandler, sound, soundInfo);
                this.CallbackWrapperHandle = GCHandle.Alloc(CallbackWrapper, GCHandleType.Pinned);
                this.EventInstance.setUserData(GCHandle.ToIntPtr(CallbackWrapperHandle));
                this.EventInstance.setCallback(this.FMODCallback,
                FMOD.Studio.EVENT_CALLBACK_TYPE.STOPPED  // Stop is the only user supported event 
                | FMOD.Studio.EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND
                | FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROY_PROGRAMMER_SOUND
                | FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROYED
                | FMOD.Studio.EVENT_CALLBACK_TYPE.STOPPED
                );
            }
            public SoundInstance GetReference()
            {
                FMODSoundInstance instance;
                Reference.TryGetTarget(out instance);
                return instance;
            }
            public bool IsAlive()
            {
                FMODSoundInstance instance;
                return Reference.TryGetTarget(out instance);
            }
            public void DestroyInstance()
            {
                if (IsAlive()) Debug.LogWarning("Destroying SoundInstance that still has an owner");
                EventInstance.release();
                EventInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
            }
            public void TimeScalePause(bool pause)
            {
                if (pause)
                {
                    if (timeScalePaused) return;
                    PLAYBACK_STATE playbackState;
                    EventInstance.getPlaybackState(out playbackState);
                    if (playbackState == PLAYBACK_STATE.PLAYING)
                    {
                        timeScalePaused = true;
                        EventInstance.setPaused(true);
                    }
                }
                else if (timeScalePaused)
                {
                    timeScalePaused = false;
                    EventInstance.setPaused(false);
                }
            }
            private void FMODCallbackHandler(FMOD.Studio.EVENT_CALLBACK_TYPE eventType)
            {
                foreach (CallbackAndMask callback in this.Callbacks)
                {
                    if (callback.IsCallbackTypeListener(eventType))
                    {
                        callback.Callback?.Invoke(callback.TranslateType(eventType));
                    }
                }
            }
            [AOT.MonoPInvokeCallback(typeof(FMOD.Studio.EVENT_CALLBACK))]
            private static FMOD.RESULT FMODUnmanagedCallback(FMOD.Studio.EVENT_CALLBACK_TYPE type, IntPtr instancePtr, IntPtr parameterPtr)
            {
                // Get Instance
                FMOD.Studio.EventInstance instance = new FMOD.Studio.EventInstance(instancePtr);
                // Retrieve the user data
                IntPtr callbackWrapperPtr;
                FMOD.RESULT result = instance.getUserData(out callbackWrapperPtr);
                if (result != FMOD.RESULT.OK)
                {
                    Debug.LogError("Failed to fetch user data for audio callback: " + result);
                }
                else if (callbackWrapperPtr != IntPtr.Zero)
                {
                    // Grab Parameters
                    GCHandle callbackWrapperHandle = GCHandle.FromIntPtr(callbackWrapperPtr);
                    FMODCallbackWrapper callbackWrapper = (FMODCallbackWrapper)callbackWrapperHandle.Target;
                    // Handle Default Actions
                    switch (type)
                    {
                        case FMOD.Studio.EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND:
                            {
                                FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES programmerSoundProperties =
                                    (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(
                                        parameterPtr, typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
                                programmerSoundProperties.sound = callbackWrapper.Sound.handle;
                                programmerSoundProperties.subsoundIndex = callbackWrapper.SoundInfo.subsoundindex;
                                Marshal.StructureToPtr(programmerSoundProperties, parameterPtr, false);
                                break;
                            }
                        case FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROY_PROGRAMMER_SOUND:
                            {
                                FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES parameter =
                                    (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(
                                        parameterPtr, typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
                                FMOD.Sound sound = new FMOD.Sound(parameter.sound);
                                sound.release();
                                break;
                            }
                        case FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROYED:
                            {
                                callbackWrapperHandle.Free();
                                break;
                            }
                    }
                    // Call User Callbacks
                    callbackWrapper.UserCallbackHandler?.Invoke(type);
                }
                return FMOD.RESULT.OK;
            }
            private class FMODSoundInstance : SoundInstance
            {
                private FMODSoundInstanceContainer Container;
                private bool meteringEnabled;
                public FMODSoundInstance(FMODSoundInstanceContainer container) => this.Container = container;
                public override string GetEventName() => Container.EventKey;
                public override void OnStateChange(Action<SoundInstanceState> callback, SoundInstanceState stateMask)
                {
                    // Sanity Checks
                    if (callback == null) return;
                    if (!Container.EventInstance.isValid())
                    {
                        Debug.LogError("Can't set callback on destroyed sound instance");
                        callback(SoundInstanceState.Error);
                        return;
                    }
                    if (stateMask != SoundInstanceState.Stopped)
                    {
                        Debug.LogError("Only Stopped and Error state are supported for callback");
                        return;
                    }
                    // Store Callback
                    Container.Callbacks.Add(new CallbackAndMask(callback, stateMask));
                }
                public override void SetParameter(string parameter, float value, bool skipSeek)
                {
                    // Sanity
                    if (!Container.EventInstance.isValid())
                    {
                        Debug.LogError("Can't set parameter on destroyed sound instance");
                        return;
                    }
                    FMOD.RESULT result = Container.EventInstance.setParameterByName(parameter, value, skipSeek);
                    if (result != FMOD.RESULT.OK)
                    {
                        Debug.LogError("Failed to set variable " + parameter + " to " + value + " with result " + result);
                    }
                }
                public override void Start()
                {
                    // Sanity
                    if (!Container.EventInstance.isValid())
                    {
                        Debug.LogError("Can't start a destroyed sound instance");
                        return;
                    }
                    Container.EventInstance.start();
                }
                public override void Stop(bool immediate = false)
                {
                    if (!Container.EventInstance.isValid())
                    {
                        Debug.LogError("Can't attach a destroyed sound instance");
                        return;
                    }
                    Container.EventInstance.stop(immediate ? FMOD.Studio.STOP_MODE.IMMEDIATE : FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
                }
                public override void Pause(bool pause)
                {
                    // Sanity
                    if (!Container.EventInstance.isValid())
                    {
                        Debug.LogError("Can't pause a destroyed sound instance");
                        return;
                    }
                    Container.EventInstance.setPaused(pause);
                }
                public override void AttachToGameObject(GameObject gameObject)
                {
                    // Sanity
                    if (!Container.EventInstance.isValid())
                    {
                        Debug.LogError("Can't attach a destroyed sound instance");
                        return;
                    }
                    FMODUnity.RuntimeManager
                        .AttachInstanceToGameObject(
                            Container.EventInstance, gameObject.transform, gameObject.GetComponent<Rigidbody2D>());
                }
                public override void DetachFromGameObject()
                {
                    // Sanity
                    if (!Container.EventInstance.isValid())
                    {
                        Debug.LogError("Can't detach a destroyed sound instance");
                        return;
                    }
                    FMODUnity.RuntimeManager.DetachInstanceFromGameObject(Container.EventInstance);
                }
                public override float GetBusLevelDBs()
                {
                    if (!Container.EventInstance.isValid())
                    {
                        Debug.LogError("Can't get levels for a destroyed sound instance");
                        return MinVolumeDBs;
                    }
                    // Fetch channel group
                    FMOD.ChannelGroup channelGroup;
                    FMOD.RESULT result = Container.EventInstance.getChannelGroup(out channelGroup);
                    if (result == FMOD.RESULT.ERR_STUDIO_NOT_LOADED) return MinVolumeDBs;
                    if (result != FMOD.RESULT.OK)
                    {
                        Debug.LogError($"Failed to fetch channel group to check metering {result}");
                        return MinVolumeDBs;
                    }
                    // Fetch DSP
                    FMOD.DSP dsp;
                    result = channelGroup.getDSP(0, out dsp);
                    if (result != FMOD.RESULT.OK)
                    {
                        Debug.LogError($"Failed to fetch dsp to check metering {result}");
                        return MinVolumeDBs;
                    }
                    // Enable metering if necessary
                    if (!meteringEnabled)
                    {
                        dsp.setMeteringEnabled(false, true);
                        meteringEnabled = true;
                    }
                    // Fetch metering info
                    FMOD.DSP_METERING_INFO meteringInfo;
                    dsp.getMeteringInfo(IntPtr.Zero, out meteringInfo);
                    float rms = 0f;
                    for (int i = 0; i < meteringInfo.numchannels; i++)
                    {
                        rms += meteringInfo.rmslevel[i] * meteringInfo.rmslevel[i];
                    }
                    rms = Mathf.Sqrt(rms / (float)meteringInfo.numchannels);
                    float db = rms > 0 ? 20.0f * Mathf.Log10(rms * Mathf.Sqrt(2.0f)) : MinVolumeDBs;
                    db = Mathf.Clamp(db, MinVolumeDBs, MaxVolumeDBs);
                    return db;
                }
            }
            public class CallbackAndMask
            {
                public SoundInstance.SoundInstanceState Mask;
                public Action<SoundInstance.SoundInstanceState> Callback;
                public CallbackAndMask(Action<SoundInstance.SoundInstanceState> callback, SoundInstance.SoundInstanceState mask)
                {
                    this.Mask = mask;
                    this.Callback = callback;
                }
                public bool IsCallbackTypeListener(FMOD.Studio.EVENT_CALLBACK_TYPE eventType)
                {
                    return (TranslateType(eventType) & Mask) != 0;
                }
                public SoundInstance.SoundInstanceState TranslateType(FMOD.Studio.EVENT_CALLBACK_TYPE eventType)
                {
                    switch (eventType)
                    {
                        case FMOD.Studio.EVENT_CALLBACK_TYPE.STOPPED:
                            return SoundInstance.SoundInstanceState.Stopped;
                    }
                    return 0;
                }
            }
        }
    }
    [StructLayout(LayoutKind.Sequential)]
    class FMODCallbackWrapper
    {
        // User Callback Handler 
        public Action<FMOD.Studio.EVENT_CALLBACK_TYPE> UserCallbackHandler;
        // Dialogue Parameters
        public FMOD.Sound Sound;
        public FMOD.Studio.SOUND_INFO SoundInfo;
        public FMODCallbackWrapper(Action<FMOD.Studio.EVENT_CALLBACK_TYPE> userCallbackHandler)
        {
            this.UserCallbackHandler = userCallbackHandler;
        }
        public FMODCallbackWrapper(
            Action<FMOD.Studio.EVENT_CALLBACK_TYPE> userCallbackHandler,
            FMOD.Sound sound,
            FMOD.Studio.SOUND_INFO soundInfo) : this(userCallbackHandler)
        {
            this.Sound = sound;
            this.SoundInfo = soundInfo;
        }
    }
}
I’m not sure what’s going on, but audio does on on the MacOS build.
The script 'Audio.FMODSound' could not be instantiated! 
(Filename: ./Runtime/Scripting/ManagedReference/SerializableManagedRef.cpp Line: 227)
I’ve got a reproduction uploaded call Reproduction 2. I built that for another project, but it’s possible to reproduce this error with the same project.