ScriptableObject loses data when I hit Play
I want to use SortedSet for Auto-sorted-list on my ScriptableObject to store data like this:
[CreateAssetMenu(fileName = "ScoreList", menuName = "ScriptableObject/ScoreList...")]
public class ScoreList : ScriptableObject
{
public SortedSet<Score> scores = new SortedSet<Score>();
}
My Class Score:
[System.Serializable]
public class Score : System.IComparable<Score>
{
public float percent;
public Material material;
public Sprite sprite;
public int CompareTo(Score other)
{
float ret = percent - other.percent;
if (System.Math.Abs(ret) < 0.001)
return 0;
else
return ret < 0 ? -1 : 1;
}
}
Unfortunately Unity don't support SortedSet in Inspector windows so I make a CustomEditor:
[CustomEditor(typeof(ScoreList))]
public class ScoreListEditor : Editor
{
ScoreList scoreList;
Score score, delete = null;
bool IsOpen = false;
private void OnEnable()
{
scoreList = target as ScoreList;
score = new Score();
}
private void OnDisable()
{
EditorUtility.SetDirty(scoreList);
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
GUILayout.Space(5);
IsOpen = EditorGUILayout.BeginFoldoutHeaderGroup(IsOpen, "Score list (" + scoreList.scores.Count + ")", EditorStyles.foldoutHeader);
foreach (Score score in scoreList.scores)
{
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUI.BeginDisabledGroup(true);
score.percent = EditorGUILayout.FloatField("Score percent", score.percent);
if (IsOpen)
{
score.material = EditorGUILayout.ObjectField("2D Sprite", score.material, typeof(Material), true) as Material;
score.sprite = EditorGUILayout.ObjectField("2D Sprite", score.sprite, typeof(Sprite), true) as Sprite;
}
EditorGUI.EndDisabledGroup();
if (IsOpen)
if (GUILayout.Button("Remove this"))
delete = score;
EditorGUILayout.EndVertical();
}
if (delete.NotEqualsNull())
{
scoreList.scores.Remove(delete);
score = delete;
delete = null;
EditorUtility.SetDirty(scoreList);
}
EditorGUILayout.EndFoldoutHeaderGroup();
GUILayout.Space(10);
EditorGUILayout.LabelField("Add new Score");
score.percent = EditorGUILayout.Slider("Score percent", score.percent, 0, 1);
score.material = EditorGUILayout.ObjectField("2D Sprite", score.material, typeof(Material), true) as Material;
score.sprite = EditorGUILayout.ObjectField("2D Sprite", score.sprite, typeof(Sprite), true) as Sprite;
if (GUILayout.Button("Add"))
{
scoreList.scores.Add(score);
EditorUtility.SetDirty(scoreList);
score = new Score();
}
}
}
After that, I can add my Score to scores and seen like it work! But it don't working properly after all. Whenever I hit "Play", all my data gone away! I try store data after hit Play but it's still not working I try figure out by myself on Internet, on similar problem I find but after all, I can't see what wrong in my code.
Answer by goten265 · Jun 22, 2020 at 02:53 PM
Hello Takimiri, I am not a pro a unity or CSharp but i think that you forgot the [SerializeField] in the ScoreList this should fix it:
[CreateAssetMenu(fileName = "ScoreList", menuName = "ScriptableObject/ScoreList...")]
public class ScoreList : ScriptableObject
{
[SerializeField] public SortedSet<Score> scores = new SortedSet<Score>();
}
Your answer
Follow this Question
Related Questions
Abillity system for turn based strategy 0 Answers
Scriptable Objects not present in Built Version 1 Answer
Custom inspector - How to serialize scene objects in ScriptableObject? 0 Answers
type mismatch on texture 2D inside scriptable object 0 Answers
Saving reference to a ScriptableObject with JsonUtility 1 Answer