Saving ScriptableObject Skill List
Posted: Thu May 21, 2020 9:58 am
Here's one way to to save a dynamic list of ScriptableObject assets in the Dialogue System.
Unity does not serialize ScriptableObject references. For example, say you have a ScriptableObject like this:
And the player has a component that maintains a list of skills:
To "save" skills, you can record which elements of PlayerSkills.skills are in the skill database and represent it in a string. To "restore" skills, you can reconstruct the skills list from the string. For example:
Unity does not serialize ScriptableObject references. For example, say you have a ScriptableObject like this:
Code: Select all
public class Skill : ScriptableObject
{
public string description;
}
Code: Select all
public class PlayerSkills : MonoBehaviour
{
public List<Skill> skills;
public void LearnSkill(Skill newSkill) { skills.Add(newSkill); }
}[code]
Unity cannot serialize and deserialize the List<Skill>. One workaround is to use an additional ScriptableObject asset that references all Skill assets:
[code]public class SkillDatabase : ScriptableObjects
{
public List<Skill> allSkills; //<-- ASSIGN ALL SKILL ASSETS.
}
Code: Select all
public class PlayerSkills : MonoBehaviour
{
public SkillDatabase skillDatabase; //<-- ASSIGN SKILL DATABASE ASSET.
public List<Skill> skills;
public void LearnSkill(Skill newSkill) { skills.Add(newSkill); }
public string SaveSkillsToString()
{
var indices = new List<string>();
foreach (var skill in skills)
{
indices.Add(skillDatabase.allSkills.IndexOf(skill));
}
return string.Join(",", indices);
// You could save this string in a Saver component or use DialogueLua.SetActorField().
}
public void RestoreSkillsFromString(string s)
{
var indices = s.Split(',');
skills.Clear();
foreach (var index in indices)
{
var skill = skillDatabase.allSkills[SafeConvert.ToInt(index)];
skills.Add(skill);
}
}
}