I have a scriptable object which holds a list of custom classes (which are Serializable). I’m populating the list via script and this works just fine but as soon as I move to a different scene or restart the editor, I lose all entries except the first one. I took a look in the .asset file and indeed it only contains the first element (even though in the inspector it still shows all 18 of them).
I thought maybe there was some reference to the scene which was being lost so I made it cloneable and checked that there were no references to anything in the scene.
(P.s. I’m using Unity 2019.1.8f1)
This seems like very strange behaviour. I have other lists of classes which work fine. It just seems to be this one.
The List variable which loses it’s data:
[Serializable]
[CreateAssetMenu (fileName = "TableTopDataArrayVariable", menuName = "General/TableTopDataArrayVariable", order = 1)]
public class TableTopDataArrayVariable : ScriptableObject {
[SerializeField]
public List<TableTop_Data> Value;
public void Set(List<TableTop_Data> value)
{
value = new List<TableTop_Data>();
Value = value;
}
}
The class that I’m creating a list of
[System.Serializable]
public class TableTop_Data : ICloneable
{
public string m_Name;
public string m_Guid;
public TableTopPlaneType m_TableTopPlaneType;
public Material m_PlaneMaterial;
public List<LightData> m_LightData = new List<LightData>();
public object Clone()
{
TableTop_Data clonedData = new TableTop_Data();
clonedData.m_Name = m_Name;
clonedData.m_Guid = m_Guid;
clonedData.m_TableTopPlaneType = m_TableTopPlaneType;
clonedData.m_PlaneMaterial = m_PlaneMaterial;
clonedData.m_LightData = new List<LightData>();
if (m_LightData.Count > 0)
{
foreach (var lightDataItem in m_LightData)
{
clonedData.m_LightData.Add(lightDataItem.Clone() as LightData);
}
}
return clonedData;
}
}
In the inspector (before switching scene or restarting the editor):
Thanks but I don’t think the cloning is the issue because I was having the same problem before I introduced the cloning (it was an attempt to get around the problem).
I wonder if maybe its because I’m modifying it from an EditorWindow and so because I’m not in Play mode, maybe there is some sort of assetdatabase refreshing that I need to do?
https://unity3d.com/how-to/architect-with-scriptable-objects has some tips on working with the serialized data, but whenever I use SO’s I can edit them at runtime or editor time and they retain the values so I’m not sure what to suggest. I don’t use any code to achieve this though.
edit:
Bear in mind ScriptableObjects are stored in project, not scene. They will never be stored in a scene, though they can be referenced. The power of scriptable objects are they are not stored in scenes.
On the first line a list is created a replaces a reference passed as parameter. On the second line reference to the newly created list (wich is empty) is saved to the class field. If you this this code copies a list, then this is the error.
Try to replace that code with
Value = new List<TableTop_Data>(value);
This line creates a new empty list, copies items from another list, and saves reference to that new list to the class field named Value.
Yes, I agree that this code is redundant. Actually I haven’t even been using the set function. Instead I’ve just been assigning to the Value directly seeings as it is public. i.e. Far_BackPlaneData.Value.Add(tableTop_Data.Clone as TableTop_Data);
So I’ve just noticed that If I manually resize the list size in the inspecter to be one bigger, then it gets written to the file properly… this gives me a work around but I’d obvs like to fix it properly if poss.
It also makes me think it is indeed something to do with manually telling the editor that it needs to write it’s cache to the files or something.?.
In this case setting asset dirty using Unity editor untilities may help you.
And if not, I suggest you use SerializedObject instance for editing asset as unity inspector does. But I hope just setting it dirty will help. I thing the reason behind this is what Unity may know when you change field value or add items during inspector. But there’s no way for Unity editor to get notification when you add items directly to the list.
Be sure that the inspector isn’t in debug mode when adding and removing references manually to the list- I believe it’ll bypass both the dirtying and AssetDatabase’s SaveAssets function call if you are, since it’s not going through the inspector script at all.