This comes from a large complicated project, so I have tried to prepare a shorter code example. However, the provided example works correctly. I’ve been back and forward over it, and I can’t see how it differs, so I’m really just looking for any possible causes of the problem:
- A field holding an array of
ScriptableObjectfails to retain data when you quit and reload Unity.
–
I have an array of ScriptableObject held on a MonoBehaviour. In certain circumstances these are also saved into the AssetDatabase, hence the use of ScriptableObject. For this problem, they are not saved to the database.
A custom editor allows you to create new instances, and edit the data on each item. This works fine, and when you run the game the data is not lost. The data is only lost when you quit and reload Unity.
There is a lot other data held on and under the MonoBehaviour which does not suffer from this problem. However this is the only data which extends from ScriptableObject. What’s confusing me mostly is the field holding the array itself seems to be lost rather than the individual items - on load the array is completely empty, rather than being full of null.
The following code I wrote in an attempt to isolate the problem - this should reflect what the main code is doing exactly, but frustratingly this works exactly as expected.
–
Test001.cs
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class Test001 : MonoBehaviour
{
[SerializeField]
private Test001Item[] items;
public IEnumerable<Test001Item> Items
{
get
{
if (this.items == null) { this.items = new Test001Item[0]; }
return this.items;
}
}
public Test001Item AddItem()
{
Test001Item item = ScriptableObject.CreateInstance<Test001Item>();
List<Test001Item> items = this.Items.ToList();
items.Add(item);
this.items = items.ToArray();
return item;
}
}
Test001Item.cs
using System;
using UnityEngine;
[Serializable]
public class Test001Item : ScriptableObject
{
[SerializeField]
private string data;
public string Data { get { return this.data; } set { this.data = value; } }
}
Editor/Test001Editor.cs
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Test001))]
public class Test001Editor : Editor
{
public static void DrawInspector(Test001 test)
{
GUI.changed = false;
if (GUILayout.Button("Add")) { test.AddItem(); }
foreach (Test001Item item in test.Items)
{
Test001ItemEditor.DrawInspector(item);
}
if (GUI.changed) { Test001Editor.SaveData(test); }
}
public override void OnInspectorGUI()
{
Test001 test = (Test001)this.target;
Test001Editor.DrawInspector(test);
}
private static void SaveData(Test001 test)
{
EditorUtility.SetDirty(test);
foreach (Test001Item item in test.Items)
{
EditorUtility.SetDirty(item);
}
}
}
Editor/Test001ItemEditor.cs
[CustomEditor(typeof(Test001Item))]
public class Test001ItemEditor : Editor
{
public static void DrawInspector(Test001Item item)
{
item.Data = EditorGUILayout.TextField(item.Data);
}
}
–
As I say, this does not recreate this issue, but I can’t see what the difference is between this and my main code. As such I’m just looking for any possible causes of the problem.
- Does anyone have any ideas as to why an array of
ScriptableObjects would be lost on quit only?