ScriptedImporter and ScriptableObject
I have an issue with ScriptedImporter and ScriptableObjects where a ScriptableObject imported through a custom ScriptedImporter appears empty when referenced in another object.
Here is the ScriptableObject class that is imported which is basically a container of Vector2:
public class SampleSequences : ScriptableObject
{
public List<List<Vector2>> Sequences = new List<List<Vector2>>();
}
The ScriptedImporter is in charge of reading an asset file and filing in the Sequences member with the Vector2s, as such:
[ScriptedImporter(1, "sseq")]
public class SampleSequenceImporter : ScriptedImporter
{
public override void OnImportAsset(AssetImportContext ctx)
{
SampleSequences sampleSequences = ScriptableObject.CreateInstance<SampleSequences>();
var lines = File.ReadLines(ctx.assetPath);
var culture = CultureInfo.GetCultureInfo("en-US");
Vector2Sequence currentSequence = null;
foreach (string line in lines)
{
if (line.StartsWith("//"))
{
if (line.StartsWith("// Sequence"))
{
currentSequence = new Vector2Sequence();
sampleSequences.Sequences.Add(currentSequence);
}
}
else
{
var tokens = line.Split(new char[] { ' ' });
var sample = new Vector2();
if (!float.TryParse(tokens[0], NumberStyles.Float, culture, out sample.x))
{
DestroyImmediate(sampleSequences);
return;
}
if (!float.TryParse(tokens[1], NumberStyles.Float, culture, out sample.y))
{
DestroyImmediate(sampleSequences);
return;
}
currentSequence.Add(sample);
}
}
ctx.AddObjectToAsset("MainAsset", sampleSequences);
ctx.SetMainObject(sampleSequences);
}
}
When I break in the OnImportAsset method, I see the SampleSequences object is properly filled with 100 elements in the Sequences property. Now the other ScriptableObject referencing this "imported" SampleSequences object goes like this:
[CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/Config", order = 1)]
public class Config : ScriptableObject
{
public SampleSequences SampleSource;
public int SampleSequenceIndex;
private void OnEnable()
{
var sequenceIndex = SampleSequenceIndex % SampleSource.Sequences.Count;
}
}
I created an instance of this Config object through the asset menu and set its SampleSource property to the imported SampleSequences object. So, on paper, I would assume that my Config object should have a reference to a SampleSource object with 100 elements in it. Unfortunately, when I put a breakpoint inside the OnEnable() method of the Config object, I see that there is indeed a SampleSequences object in the SampleSource property but with 0 elements in it! What am I doing wrong?
PS: I've also tried calling directly AssetDatabase.LoadAssetAtPath in the OnEnable method of the Config object but get the same SampleSequences object with empty elements.
Answer by oprat · Sep 09, 2019 at 07:57 AM
Problem solved!!!
The problem was related to serialization as the SampleSequences class had a nested container property in the form of a List of List and this is not serializable (see "Serialization Rules" in Script Serialization
The fix was to break down the innermost List into a custom internal class.
Your answer
Follow this Question
Related Questions
How can I load an custom file from the Assets folder? 1 Answer
Unity3D ScriptableObject with UnityEvent not saving event parameter 0 Answers
How to break reference from .asset classes and runtime copied values? 2 Answers
Serializable Class On ScriptableObject Null when loaded from AssetBundle 2 Answers