Search Unity

Keep references in EditorWindow after scripts recompiling

Discussion in 'Editor & General Support' started by fra3point, Oct 3, 2020.

  1. fra3point

    fra3point

    Joined:
    Aug 20, 2012
    Posts:
    269
    Hello,

    I'm struggling with this editor scripting issue...

    My goal is to create a Texture2D inside the Editor Window and keep its reference alive after recompiling.

    If I use a classic variable inside the window, everything works fine.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. public class RecompileTest1 : EditorWindow
    5. {
    6.     public Texture2D tex;
    7.    
    8.     [MenuItem("Window/Recompile Test 1")]
    9.     static void Init()
    10.     {
    11.         RecompileTest1 recompileTest = (RecompileTest1) GetWindow(typeof(RecompileTest1));
    12.         recompileTest.Show();
    13.     }
    14.  
    15.     private void Awake()
    16.     {
    17.         tex = Texture2D.whiteTexture;
    18.     }
    19.  
    20.     void OnGUI()
    21.     {
    22.         if (tex == null)
    23.         {
    24.             GUILayout.Label("Texture is null", EditorStyles.boldLabel);
    25.         }
    26.         else
    27.         {
    28.             GUILayout.Label("Texture is NOT null", EditorStyles.boldLabel);
    29.             GUI.DrawTexture(new Rect(50, 50, 100, 100), tex, ScaleMode.ScaleToFit);
    30.         }
    31.  
    32.     }
    33. }

    But if this texture is created inside an instance which is referenced in the window, after recompiling the instance is gone and the texture too...

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. public class TextureContainer
    5. {
    6.     public Texture2D tex;
    7. }
    8.  
    9. public class RecompileTest2 : EditorWindow
    10. {
    11.     private TextureContainer container;
    12.    
    13.     [MenuItem("Window/Recompile Test 2")]
    14.     static void Init()
    15.     {
    16.         RecompileTest2 recompileTest2 = (RecompileTest2) GetWindow(typeof(RecompileTest2));
    17.         recompileTest2.Show();
    18.     }
    19.  
    20.     private void Awake()
    21.     {
    22.         container = new TextureContainer();  //this instance will be NULL after recompiling scripts
    23.         container.tex = Texture2D.whiteTexture; //tex is now inside the container
    24.     }
    25.  
    26.     void OnGUI()
    27.     {
    28.         if (container == null)
    29.         {
    30.             GUILayout.Label("Container is null, we can't access the texture!", EditorStyles.boldLabel);
    31.         }
    32.         else
    33.         {
    34.             GUILayout.Label("Container is NOT null, and we can access the texture", EditorStyles.boldLabel);
    35.             GUI.DrawTexture(new Rect(50, 50, 100, 100), container.tex, ScaleMode.ScaleToFit);
    36.         }
    37.  
    38.     }
    39. }

    Is there something I can do to keep these references?

    Thank you,

    Francesco
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    Marking TextureContainer as
    [Serializable]
    would be a good start, as well as marking the private field with
    [SerializeField]
     
    fra3point likes this.
  3. fra3point

    fra3point

    Joined:
    Aug 20, 2012
    Posts:
    269
    Thanks man, your solution works. Fast as hell!!!!

    One note is that the inner fields must be non-static, otherwise they are destroyed.
     
  4. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    Well yeah, static fields don't belong to any object, so they will be lost.
     
    fra3point likes this.