Last Updated: November 19, 2020
· catchco

ScriptableObject Gotcha

Making changes to a ScriptableObject during play mode has different consequences depending on how you load the resource.

Consider the following lines:

// Load the scriptable object from an asset file
var levelResource = (Level)Resources.Load("Level_1.asset");

// Line A
_currentLevel = (Level)ScriptableObject.Instantiate(levelResource);

// Line B
_currentLevel = levelResource;

While the last two lines look similar the difference is important: The level asset on line A will be cloned but on line B the original asset will be referenced.

This distinction is critical. Using the method on line B, Any changes to the Level ScriptableObject during Play Mode will be permanently recorded to the asset potentially leading to a loss of data.

On the flip-side, by cloning the Level asset as per line B, any modifications to the original asset will not be propagated to existing cloned instances during play mode. You will have to sync the objects manually.

Related protips:

Improved PlayerPrefs for Unity