How to change the contents of a ScriptableObject after building a project?

908 Views Asked by At

I want to change a value in a ScriptableObject after building in Unity. However, it worked fine before the build, but the SO value did not change in the exe file after the build.

However, the list of other SOs is accessible. You can't change exactly the int value. Why is that? And what is the solution?

I want to assign values dynamically to my SO.

3

There are 3 best solutions below

1
On

In editor mode before building, you can directly receive the address of the SO value and change the value. However, to change the value of SO after building, you can create it dynamically within the project and then refer to it to change it. When creating, use CreateAsset, and it is recommended to write json or XML to save it.

0
On

EditorUtility.SetDirty(ScriptObject) is not able to use after the build, so the ScriptObject Asset is not able to modify after build. (actually, you can't build a game with this UnityEditor method).

So, just use another serialize method to store your data, as Unity Doc marks the ScriptObject only use for static config.

0
On

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.