- Home /
Serializing a collection of ScriptableObjects to an ASSET file?
Hi all,
I have tried to make my code as simple/reduced as possible to try to understand what's going on. I have a class representing the data I want to serialize, like this:
using UnityEngine;
public class TestData : ScriptableObject
{
public int theValue;
}
... and a class which represents a serializable collection of TestData objects, like this:
using UnityEngine;
public class TestCollection : ScriptableObject
{
public TestData [] myArray;
}
Ok, so what I want to do is to create a collection of data objects and save this collection to an ASSET file, which will be loaded in runtime through Unity's Resources.Load() method. I have created a simple script which creates two menus in Unity Editor: one of them is used to create an asset file containing a predefined TestCollection of TestData objects, and the other one is used to load the saved TestCollection from that created file and print the values of all the TestData objects contained in it.
using UnityEngine;
using UnityEditor;
public class TestMenu
{
[MenuItem("TEST/Create asset")]
public static void testCreate()
{
TestCollection newAsset = ScriptableObject.CreateInstance<TestCollection>();
newAsset.myArray = new TestData[3];
for ( int t = 0; t < 3; t++ )
{
newAsset.myArray[t] = ScriptableObject.CreateInstance<TestData>();
newAsset.myArray[t].theValue = (t+1)*100; // initialize data objects with values 100, 200 and 300...
}
AssetDatabase.CreateAsset( newAsset, "Assets/Resources/MyTestAsset.asset" );
}
[MenuItem("TEST/Print values")]
public static void testPrint()
{
TestCollection theAsset = Resources.Load<TestCollection>( "MyTestAsset" );
foreach ( TestData x in theAsset.myArray )
Debug.Log( x.theValue.ToString() ); // <-- EXCEPTION IS THROWN HERE
}
}
Now, the problem is that Unity seems to be serializing the TestCollection object correctly, while it is not serializing the TestData objects in it. If I click the "Create asset" menu and then click the "Print values" menu, the values of the objects stored in the asset file are printed correctly: 100, 200 and 300, respectivelly. But then, if I enter in play mode and click the "Print values" menu, a NullReferenceException is thrown when trying to execute the "Debug.Log( x.theValue.ToString() )" line ("x" is null), which means that the serialization of the TestData objects have failed!
So, is there any way to serialize a collection of ScriptableObject objects to an asset file? What am I missing here..?
Answer by Bunny83 · Nov 27, 2014 at 04:24 PM
ScriptableObjects need to be serialized on their own. So you either have to serialize them as seperate assets or (what will be more common) add them to your base asset with AssetDatabase.AddObjectToAsset.
Hi, Bunny83, thank you for your quick reply! I have tried what you suggested before trying to create a collection based on ScriptableObject. But when I tried to retrieve my data back by using "Resources.LoadAll()", only the first object from the asset was being returned.
By reading your answer and the documentation again, I found out that was missing something from the docs: after adding multiple assets to a file, you need to reimport that file by calling AssetDatabase.ImportAsset(), so that the asset gets updated by Unity with all the added objects! Shame on me for not noticing this before haha
Thank you very much
Your answer
Follow this Question
Related Questions
AssetDatabase.LoadAssetAtPath() not working after any sort of project change. 0 Answers
Scriptable Object references if not saved in AssetDatabase? 1 Answer
.asset file containing ScriptableObject is empty on openingUnity 1 Answer
Using System.Object in ScriptableObject 1 Answer
Custom assets give Missing (Mono Script) 0 Answers