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

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:
    267
    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,697
    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:
    267
    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,697
    Well yeah, static fields don't belong to any object, so they will be lost.
     
    fra3point likes this.