The other answers already address the issue, but I think I have something to add. ScriptableObject are placed inside the build like any other object, and you cannot change them without creating a new build. You can still change their value after loaded in memory, as you would do with any class that does not inherit anything, but it's not their job to save or persist the change across different executions, neither do they call OnValidate
, Reset
or any editor methods outside the Unity Editor. Once you build the executable, it no longer has anything to do with your Unity project, and exists "on its own".
Yet, as stated, you can change its value during the play, but be aware that if you create a serialized field, in the editor it will persist the value across play sessions, while in a build it will not:
class Example : ScriptableObject{
public int ANormalProperty { get; set; }
public int ASerializedField;
}
// Suppose you have a reference to the scriptable
Example example;
// properties are not serialized by default, it will not affect the object in build.
example.ANormalProperty = 5;
// In Unity Editor, it will persist the change to the ScriptableAsset and across play sessions,
// but in a build, it will persist only during the execution, and reset each execution.
example.ASerializedField = 10;
Updating an asset after build (DLC)
However, you may be able to update a ScriptableObject after build by making it an Addressable. Addressables can be configured so that you only need to build a bundle and update the bundle file in the build, without updating the exe or the rebuilding the whole project. This can be used to add content on demand (DLC), for example.
Saving player data
If your intention was just to save a value as a game save, then you might be more interested in PlayerPrefs than ScriptableObjects. You may even implement a game save using the core System.IO.File
to create a file with the values you want to persist, but PlayerPrefs allows you to save in a multiplatform fashion, without knowledge about the filesystem your game is running on.
To save a value with a PlayerPrefs you just call:
PlayerPrefs.SetString("playerName", "My Player 1");
PlayerPrefs.SetInt("lifes", 1);
PlayerPrefs.SetFloat("currentSpeed", 1.5f);
PlayerPrefs.Save();
and you load with the GetString
, GetInt
, GetFloat
counterparts at any moment after the game is running.