I have an asset file generated from a scriptable object, and this is assigned to a variable in a component. This is all good, except that when I click play, unity sets the scriptable object to a new instance instead of keeping the values I assigned in the editor. What would cause this to happen and how do I stop it?
Ah, you’re using a custom editor class…
My only guesses are that if you’re using a custom inspector to edit the object, you’re not correctly setting it dirty after edits; or your custom inspector is editing some fields which are, for whatever reason, not serializable by Unity. Try disabling the custom inspector, and see what Unity shows in the default inspector - that is all it knows how to serialize. So before enabling the custom inspector, make sure all the non-derived data in the class is showing up in the default inspector, and fix that first if it’s not.
Then test again, still without the custom inspector, to see if changes you make in the default inspector get lost when you play the scene - they should not get lost.
Finally re-enable the custom inspector, and if it’s still broken, ensure you’re correctly setting the dirty flags, either by testing GUI.changed or by tracking yourself whether there are significant changes.
Here’s a cut-down example from my own code:
public class DroneInfo : ScriptableObject
{
public string Name;
public string Description;
public int Offense;
public int Defense;
public int Agility;
public string SpecialAbility;
public string Rarity;
public Color DroneBodyColor;
public Color DroneDetailColor;
public Color DroneEyeColor;
public static Color RandomColor()
{
Color color;
do
{
color = new Color(Random.value, Random.value, Random.value, 1);
} while (color.r + color.g + color.b < 0.5f);
return color;
}
}
[CustomEditor(typeof(DroneInfo))]
public class DroneInfoEditor : Editor
{
private DroneInfo DroneInfo { get { return (DroneInfo)target; } }
private void ColorField(string label, ref Color color)
{
var oldColor = color;
color = EditorGUILayout.ColorField(label, color);
color.a = 1;
if (oldColor != color)
EditorUtility.SetDirty(target);
}
public override void OnInspectorGUI()
{
GUILayout.BeginVertical();
ColorField("Body Color", ref DroneInfo.DroneBodyColor);
ColorField("Detail Color", ref DroneInfo.DroneDetailColor);
ColorField("Eye Color", ref DroneInfo.DroneEyeColor);
if (GUILayout.Button("Randomize Colors"))
{
DroneInfo.DroneBodyColor = DroneInfo.RandomColor();
DroneInfo.DroneDetailColor = DroneInfo.RandomColor();
DroneInfo.DroneEyeColor = DroneInfo.RandomColor();
EditorUtility.SetDirty(target);
}
GUILayout.EndVertical();
}
}