This is really confusing me, especially given it is such a basic thing that I have done hundreds of times.
Note: All of the code below is typed in by hand rather than copy/pasted so may contain typos. Some names below have been changed to protect the innocent and the company
Problem: Only the initial values of a Serializable class are saved in the ScriptableObject asset. Any changes to those values in the inspector are not saved to the asset, though they do persist through assembly reloads. The values are lost upon a restart of Unity.
Setup Detail:
[System.Serializable]
public class RandomFloatProperty
{
public float minValue;
public float maxValue;
public string propertyName;
// constructor that takes string and sets name
}
public class PropertyPreset : ScriptableObject
{
public List<RandomFloatProperty> Properties;
[MenuItem("Assets/Create/Preset")]
public static void CreateAsset()
{
PropertyPreset asset = ScriptableObject.CreateInstance<PropertyPreset>();
asset.Properties = new List<RandomFloatProperty>();
RandomFloatProperty prop1 = new RandomFloatProperty("Scale");
prop1.minValue = 1;
prop1.maxValue = 2;
RandomFloatProperty prop2 = new RandomFloatProperty("Jitter");
asset.Properties.Add(prop1);
asset.Properties.Add(prop2);
// this is just a helper method we use internally that handles the asset creation, don't worry about it. It isn't important.
ProjectWindow.CreateAsset(asset, "DefaultPreset.asset");
}
}
After creating an asset, I can look in the .asset file and see the proper values, including the property names, and the minValue and maxValue presets on the scale property. Additionally these show up properly as expected in the inspector, and the values from the .asset file are read properly. I tested this by modifying the asset file directly, and the value in the inspector updated accordingly.
If I go into the inspector and change a property on a RandomFloatProperty, the value updates in the inspector and the value appears to be properly updated and retained. The updated value will persist through an assembly reload for example, including entering and leaving play mode.
However, any of those changes made in the inspector never get written back out to the .asset file, so if you close Unity and re-open it all the values revert to the default!
I have tried decorating every filed with [SerializeField] even though that should not be necessary with public fields, but that made no difference.
I’ve been staring at this for about 4 hours now and nothing seems to make any sense. It should work, has worked in tons of other code, so I have no idea what I am missing.
Can anyone help?