# Correct way of using RuntimeManager in editor

**URL:** <https://qa.fmod.com/t/correct-way-of-using-runtimemanager-in-editor/20611>\
**Category:** Unity\
**Tags:** unity, csharp\
**Created:** [September 1, 2023, 6:24pm UTC](https://qa.fmod.com/t/correct-way-of-using-runtimemanager-in-editor/20611 "2023-09-01T18:24:54Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![nicolasmanz](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/nicolasmanz/32/1965_2.png) [@nicolasmanz](https://qa.fmod.com/u/nicolasmanz)\
**Post date:** [September 1, 2023, 6:24pm UTC](https://qa.fmod.com/t/correct-way-of-using-runtimemanager-in-editor/20611/1 "2023-09-01T18:24:54Z")

</div>

Hey there,  
I’m trying to get the MinDistance and MaxDistance attributes of events in a OnDrawGizmos, but for that I need to get the EventDescription which is only possible through RuntimeManager. In the latest updates, it can’t be accessed anymore in the Editor, and the error message encourages you to “create your own System objects”, which is essentially initializing a FMOD Studio System.

I have tried making my own FmodSystem but it doesn’t seem to be loading the events (everytime I try to get an event through ID or name, it says it doesn’t exist), and I believe it’s generating a conflict since more than one is being created in the editor.

```auto

 public static FMOD.Studio.System FmodSystem
        {
            get
            {
                if (_fmodSystem.isValid())
                    return _fmodSystem;
                var result = FMOD.Studio.System.create(out var studioSystem);
                if (result != FMOD.RESULT.OK)
                {
                    if (studioSystem.isValid())
                    {
                        studioSystem.release();
                        studioSystem.clearHandle();
                    }
                    Debug.LogError("[FMOD/STMOD] FMOD Studio System couldn't be initialized: "+result);
                }
                else
                {
                    INITFLAGS studioInitFlags = INITFLAGS.NORMAL | INITFLAGS.DEFERRED_CALLBACKS;
                    studioSystem.initialize(0, studioInitFlags, FMOD.INITFLAGS.NORMAL, IntPtr.Zero);
                    studioSystem.update();
                    _fmodSystem = studioSystem;
                }
                return _fmodSystem;
            }
        }

```

Worst thing is, if I comment out the RuntimeManager’s conditional to use it only if the game is playing, everything works out fine, but I imagine it’s not intended.

Is there any documentation or way to use FMOD’s System correctly? Thanks!

---

<div class="post-metadata">

**Author:** ![Leah\_FMOD](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/leah_fmod/32/3685_2.png) [@Leah\_FMOD](https://qa.fmod.com/u/Leah_FMOD)\
**Post date:** [September 4, 2023, 12:37am UTC](https://qa.fmod.com/t/correct-way-of-using-runtimemanager-in-editor/20611/2 "2023-09-04T00:37:29Z")

</div>

Hi,

> [@nicolasmanz](#):
>
> I have tried making my own FmodSystem but it doesn’t seem to be loading the events (everytime I try to get an event through ID or name, it says it doesn’t exist)

The only thing you seem to be missing is bank loading. To retrieve an EventDescription, you will need to load the bank it belongs to. If you’re planning to retrieve it by path, you will also need to load the Master strings bank.

> [@nicolasmanz](#):
>
> Worst thing is, if I comment out the RuntimeManager’s conditional to use it only if the game is playing, everything works out fine, but I imagine it’s not intended.

While it is _technically_ possible to call into RuntimeManager to create a Studio System, it is only designed to be used at runtime. This is because RuntimeManager destroys the created System in OnDestroy(), which only happens when a scene or game ends. so you’ll leak the Studio System in the current editor instance when calling from outside of runtime. FMOD can support up to eight Systems at once - once you call into RuntimeManager eight times from the editor, FMOD will no longer be able to create a new system until you restart the editor.

---

<div class="post-metadata">

**Author:** ![nicolasmanz](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/nicolasmanz/32/1965_2.png) [@nicolasmanz](https://qa.fmod.com/u/nicolasmanz)\
**Post date:** [September 4, 2023, 3:46pm UTC](https://qa.fmod.com/t/correct-way-of-using-runtimemanager-in-editor/20611/3 "2023-09-04T15:46:25Z")

</div>

Thanks! That worked. It does require a fair amount of code to make a System object, which I believe it’s not documented since I couldn’t find it anywhere.  
For anyone wondering, this is the final code:

```auto
public static FMOD.Studio.System FmodSystem
        {
            get
            {
                if (FMODStudioSettings == null)
                {
                    return new FMOD.Studio.System();
                }

                if (_fmodSystem.isValid())
                    return _fmodSystem;

                var result = FMOD.Studio.System.create(out var studioSystem);
                if (result != RESULT.OK)
                {
                    if (studioSystem.isValid())
                    {
                        studioSystem.release();
                        studioSystem.clearHandle();
                    }
                    Debug.LogError("FMOD Studio System couldn't be initialized: "+result);
                }
                else
                {
                    INITFLAGS studioInitFlags = INITFLAGS.NORMAL | INITFLAGS.DEFERRED_CALLBACKS;
                    studioSystem.initialize(0, studioInitFlags, FMOD.INITFLAGS.NORMAL, IntPtr.Zero);
                    studioSystem.update();
                    foreach (string bankName in GetBankPaths())
                    {
                        const string bankExtension = ".bank";
                        string bankPath;
                        string bankFolder = Application.streamingAssetsPath;
                        if (System.IO.Path.GetExtension(bankName) != bankExtension)
                        {
                            bankPath = $"{bankFolder}/{bankName}{bankExtension}";
                        }
                        else
                        {
                            bankPath = $"{bankFolder}/{bankName}";
                        }
                        studioSystem.loadBankFile(bankPath, LOAD_BANK_FLAGS.NORMAL, out _);
                    }
                    studioSystem.flushSampleLoading();
                    _fmodSystem = studioSystem;
                }
                return _fmodSystem;
            }
        }

```

Aside from that, you will need to cache the Event Descriptions to avoid lag spikes whenever you get them and then invalidate the cache at some point when FMOD’s banks are updated.

---

<div class="post-metadata">

**Author:** ![nicolasmanz](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/nicolasmanz/32/1965_2.png) [@nicolasmanz](https://qa.fmod.com/u/nicolasmanz)\
**Post date:** [January 24, 2024, 2:15pm UTC](https://qa.fmod.com/t/correct-way-of-using-runtimemanager-in-editor/20611/4 "2024-01-24T14:15:18Z")

</div>

If anyone comes across this thread and looks for an updated answer, I highly recommend **not** to use my previous code. Do not create your own StudioSystem.

Instead, in latest FMOD versions, you can use **EditorUtils.System** and then do getEventById to get the event description and any other information you might need. This works fine in the editor.

The reason I’m brining this up is because I have recently found out that plugins/spatializers affecting the event won’t be loaded in the editor with my code, and EditorUtils does it better anyway. No need to reinvent the wheel.

---

<div class="post-metadata">

**Author:** ![AldeRoberge](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/alderoberge/32/6074_2.png) [@AldeRoberge](https://qa.fmod.com/u/AldeRoberge)\
**Post date:** [June 3, 2024, 3:43pm UTC](https://qa.fmod.com/t/correct-way-of-using-runtimemanager-in-editor/20611/5 "2024-06-03T15:43:32Z")

</div>

Thanks for the update, this guided me going through the same questionning. For anyone interested, this code allows pressing a button to play a EventReference in Editor 🙂

```csharp
using FMODUnity;
using UnityEditor;
using UnityEngine;

namespace Wikwemot_AR.Modules.Definitions.Editor.Scripts.CustomEditors
{
    [CustomPropertyDrawer(typeof(EventReference))]
    public class CustomEventReferenceDrawer : EventReferenceDrawer
    {
        private static readonly Texture IconPlay = WikwemotEditorImages.LoadImage("Play.png");

        private bool _isPlaying;
        private FMOD.Studio.EventInstance _eventInstance;

        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            base.OnGUI(position, property, label);

            // Draw a button that plays the sound
            var buttonRect = new Rect(position.x, position.y + 60, 20, 20);

            if (GUI.Button(buttonRect, IconPlay))
            {
                ToggleIsPlaying(property);
            }
        }

        private void ToggleIsPlaying(SerializedProperty property)
        {
            _isPlaying = !_isPlaying;

            if (_isPlaying)
            {
                StopIfAlreadyPlaying();
                PlayNewSound();
            }
            else
            {
                _eventInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
                _eventInstance.release();
            }

            void StopIfAlreadyPlaying()
            {
                if (!_eventInstance.isValid()) return;
                _eventInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
                _eventInstance.release();
            }

            void PlayNewSound()
            {
                var eventReference = GetEventReference(property);
                if (!eventReference.HasValue) return;

                EditorUtils.LoadPreviewBanks();
                EditorUtils.System.getEventByID(eventReference.Value, out var eventDescription);
                eventDescription.createInstance(out _eventInstance);
                
                _eventInstance.start();
            }
        }

        private FMOD.GUID? GetEventReference(SerializedProperty property)
        {
            var pathProperty = property.FindPropertyRelative("Path");
            if (pathProperty != null)
            {
                var path = pathProperty.stringValue;
                return EventReference.Find(path).Guid;
            }

            return null;
        }
    }
}

```

The interesting part is the ‘PlayNewSound’ method.
