Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug Editor.CreateEditor

Discussion in 'Scripting' started by Nvizzio_Steven_G, Aug 7, 2023.

  1. Nvizzio_Steven_G

    Nvizzio_Steven_G

    Joined:
    Jan 24, 2023
    Posts:
    6
    Hello,

    I am using Editor.Create Editor as such to create an object's custom inspector in my custom window.

    Code (CSharp):
    1.  componentEditor = (AudioEventBaseDrawer)Editor.CreateEditor(currentSelectedEvent[0]);
    Now, no matter what I seem to do to the instance of component editor, it stays in memory through recompilation. The reason it is obvious that it does is that once I delete the asset in project it is related to, be it right now or later after x compilations, it's going to throw :

    SerializedObjectNotCreatableException: Object at index 0 is null

    Errors that I can't remove unless I restart Unity. In my case it's because there is an AudioSource component on the asset, which I am also creating via Editor.CreateEditor(), and when it is Destroy, the core code still searches for it (AudioSourceInspector.OnEnable).

    What I have tried to do is to make sure that I use DestroyImmediate on the Editors that I have created right before I delete the assets, I am also using DestroyImmediate on the AudioSource. I just basicly destroy everything, and it still causes the error.

    This is my code, commented (AudioEventBase exists together with an AudioSource on the gameobject) :

    Code (CSharp):
    1. private void DeleteEvents(List<AudioEventBase> events)
    2.         {
    3.             AudioManagerEditorUtilities.HandleEventMoveLoadingType(contextData,contextData.Contexts.FirstOrDefault(x => x.Name == currentSelectedContext), null, events);
    4.             foreach (AudioEventBase evnt in events)
    5.             {
    6.                 if (componentEditor != null)
    7.                 {
    8.                     //Here, Dispose calls DestroyImmediate(audioSourceEditor), which is the Editor.CreateEditor of the AudioSource, first
    9.                     componentEditor.Dispose();
    10.                     //We destroy the Editor.CreateEditor of the current AudioEventBase
    11.                     DestroyImmediate(componentEditor);
    12.                 }
    13.  
    14.                 string assetPath = AssetDatabase.GetAssetPath(evnt.gameObject);
    15.                 GameObject gameObject = evnt.gameObject;
    16.                 //We destroy the component AudioEventBase
    17.                 DestroyImmediate(evnt, true);
    18.                 foreach (AudioSource source in gameObject.GetComponents<AudioSource>())
    19.                 {
    20.                     //We destroy all possible AudioSources on the GameObject
    21.                     DestroyImmediate(source, true);
    22.                 }
    23.              
    24.                 //Finally, we destroy the GameObject itself
    25.                 AssetDatabase.DeleteAsset(assetPath);
    26.             }
    27.             AssetDatabase.Refresh();
    28.             //We destroy and recreate the list from all other existing objects that were not deleted
    29.             RefreshAudioEventList();
    30.         }

    Is there some other cleanup I am missing to avoid this error?
     
  2. Nvizzio_Steven_G

    Nvizzio_Steven_G

    Joined:
    Jan 24, 2023
    Posts:
    6
  3. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
  4. Nvizzio_Steven_G

    Nvizzio_Steven_G

    Joined:
    Jan 24, 2023
    Posts:
    6
    Im using IMGUI
     
  5. Nvizzio_Steven_G

    Nvizzio_Steven_G

    Joined:
    Jan 24, 2023
    Posts:
    6
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,494
    Why is your componentEditor destroy code inside that foreach loop? That doesn't make much sense. The UnityEditor.Editor class is a ScriptableObject. So an instance of such an Editor will not automatically disappear unless you call Destroy / DestroyImmeditate on it. The code snippets you've shown is not enough to determine what you actually do. How many instances of the editor class are you creating? Are you sure you destroy all of them? My guess would be that you create more than one editor but you don't store them all in order to destroy them later.

    Note that the editor do not stay in memory after an assembly reload. However they are recreated just like every other currently loaded and serializable UnityEngine.Object. Note that ALL UnityEngine.Object derived types are tracked and searchable through FindObjectsOfTypeAll. This is true for MonoBehaviours, gameobjects, Materials, Textures, Meshes and ScriptableObjects. EditorWindows and Editor instances are also just ScriptableObjects. They are serialized before an assembly reload and recreated afterwards.
     
  7. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,494
    Your comment seems to suggests that you assume that "componentEditor" inside that loop somehow is related to the current element in the foreach loop? This is of course a wrong assumption. If you created one editor for each of those "AudioEventBase" instances, you should have stored those editor instances somewhere in order to destroy them later.

    You might want to show more of your code. Especially how you actually create the editor instance(s).