Scriptable objects fails 2nd seralization round trip

Hi all.

Going batty with this one.
Scriptable Objects in a generic list are loosing object references on the 2nd serialization round tip.

Sample code:

using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class DataClass : ScriptableObject
{
  public string Data;
}


public class TestWindow : EditorWindow
{
  [MenuItem("Window/Debug/Show Test Window")]
  public static void OpenWindow()
  {
  //Open the window
  TestWindow __window = EditorWindow.GetWindow<TestWindow>();

  //Add some data
  __window.DataList.Add(ScriptableObject.CreateInstance<DataClass>());
  __window.DataList.Add(ScriptableObject.CreateInstance<DataClass>());
  }

  public List<DataClass> DataList = new List<DataClass>();

  void OnGUI()
  {
    foreach (var item in this.DataList)
    {
      item.Data = EditorGUILayout.TextField(item.Data, GUILayout.Width(300));
    }
  }
}

The behaviour I’m getting comes from:

  1. Open the window from the code above, 2 texts boxes will appear which I can enter some data into.
  2. Press the PIE Play button, window and data survives,
  3. Exit PIE, window and data survives
  4. Press PIE Play a second time, select the window to trigger OnGUI, both text boxes disappear and null object exceptions from line 31 will start spewing in the log.

I’ve just tested this on a fresh installation of 5.1.

I know there are other ways to achieve the result above, I was just wondering if anyone knows why this is failing this way.

A

The Scriptable objects are not persistent and are falling out of scope.

public class DataClass : ScriptableObject
{
    public string Data;

    void OnDestroy() {
        Debug.Log("Destroyed");
    }

    void OnEnable() {
        Debug.Log("Enabled");
    }

    void OnDisable() {
        Debug.Log("Disable");
    }
}


public class TestWindow : EditorWindow
{
    [MenuItem("Window/Debug/Show Test Window")]
    public static void OpenWindow()
    {
        //Open the window
        TestWindow __window = EditorWindow.GetWindow<TestWindow>();
       
        //Add some data
        __window.DataList.Add(ScriptableObject.CreateInstance<DataClass>());
        __window.DataList.Add(ScriptableObject.CreateInstance<DataClass>());

        Debug.Log("Window Opening");
    }
   
    public List<DataClass> DataList = new List<DataClass>();
   
    void OnGUI()
    {
        foreach (var item in this.DataList)
        {
            if(item != null) {
                item.Data = EditorGUILayout.TextField(item.Data, GUILayout.Width(300));
            }
        }
    }
}
1 Like

Riiight…looks like I needed to set

[Serializable]
public class DataClass : ScriptableObject
{
    public DataClass()
    {
        this.hideFlags = HideFlags.HideAndDontSave;
    }

    public string Data;
}

So…HideAndDontSave …not the most intuitive way to say ‘don’t GC my objects’ is it now :wink:

Thanks for taking the time to reply Poly.

1 Like