

A common and confusing issue in Unity projects is when ScriptableObject data appears to reset during Play Mode. Developers often report that:
This is often described as a ScriptableObject bug, but in most cases, it is expected behavior based on how Unity handles assets and runtime memory.
This article explains why ScriptableObject data resets during Play Mode and how to use reliable patterns to avoid data loss and confusion.
ScriptableObjects are asset files. They are not scene objects. When you modify them during Play Mode, you are modifying the in-memory version of that asset.
Important rules:
This is why data appears to “reset.”
Example ScriptableObject:
[CreateAssetMenu(menuName = "Game/PlayerData")]
public class PlayerData : ScriptableObject
{
public int health = 100;
}
Using it in a MonoBehaviour:
public PlayerData playerData;
void Start()
{
playerData.health -= 10;
}
During Play Mode, health becomes 90. After stopping Play Mode, it returns to 100. This is expected.
If multiple objects reference the same ScriptableObject, they all modify the same data instance.
This can cause unexpected shared state:
This is not a reset bug. It is shared asset behavior.
If Enter Play Mode settings disable Domain Reload, static fields may persist while ScriptableObjects reload differently. This can create confusing behavior where some data resets and some does not.
Check:
If you modify the asset directly instead of instantiating it, you are changing the original asset reference.
Wrong pattern:
playerData.health -= 10;
Better pattern:
private PlayerData runtimeData;
void Awake()
{
runtimeData = Instantiate(playerData);
}
Now modifications affect only the runtime copy.
To prevent shared data issues and confusion:
public PlayerData baseData;
private PlayerData runtimeData;
void Awake()
{
runtimeData = Instantiate(baseData);
}
This keeps the asset clean while allowing safe runtime changes.
Use ScriptableObjects only for:
Store runtime state in regular classes:
public class PlayerState
{
public int health;
}
If you need changes to persist, implement saving:
ScriptableObjects do not automatically save runtime changes.
If you intentionally modify ScriptableObjects in Play Mode, reset them manually:
[RuntimeInitializeOnLoadMethod]
static void ResetData()
{
// Reset static or cached data here
}
If you modify ScriptableObject values in Play Mode and see them saved permanently, it means you changed them in Edit Mode or used editor scripts. Be careful not to unintentionally overwrite asset data.
ScriptableObject data resetting during Play Mode is not a Unity bug. It is expected behavior based on how Unity loads and reloads asset data. The confusion usually comes from modifying asset instances directly instead of working with runtime copies.
By instantiating ScriptableObjects at runtime, separating configuration from game state, and implementing proper save systems, you can avoid data loss and ensure predictable behavior in both Editor and builds.
Understanding how Unity manages asset memory is essential for building stable and scalable systems.