Unity 2021.351f1中Scriptable Object运行时无法修改的问题咨询
关于Unity Scriptable Object运行时修改的问题解答
这不是Unity的Bug,而是Scriptable Object的设计特性:
- 默认情况下,Project面板里创建的Scriptable Object是磁盘上的资产文件,Unity在运行时会以只读方式加载它,防止误修改原始资产(Inspector在编辑模式下修改的是原始资产文件,运行时直接修改会污染原始数据)。
- 它并非只能存储静态数据,只是需要用正确的方式处理动态数据。
如何在Scriptable Object中存储动态数据?
有两种常用方案:
1. 运行时创建全新的内存实例
直接在代码中创建Scriptable Object的内存实例,所有修改仅作用于这个内存对象,不会影响原始资产文件:
// 你的Scriptable Object定义 public class PlayerDataSO : ScriptableObject { public int currentHP; public List<string> unlockedSkills; } // 在运行时创建并修改 void InitDynamicData() { var runtimePlayerData = ScriptableObject.CreateInstance<PlayerDataSO>(); runtimePlayerData.currentHP = 100; runtimePlayerData.unlockedSkills = new List<string> { "Fireball" }; }
2. 复制原始资产为内存副本
如果需要基于原始静态数据(比如初始技能列表)进行动态修改,可以用Instantiate()复制原始资产,得到内存中的独立副本:
public PlayerDataSO originalStaticData; // 在Inspector中拖入原始SO资产 void Start() { // 创建副本,后续修改不会影响原始资产 var dynamicPlayerData = Instantiate(originalStaticData); dynamicPlayerData.currentHP -= 30; // 修改动态数据 }
额外注意事项
- 运行时创建的内存实例或副本,游戏关闭后数据会丢失。如果需要持久化这些动态数据,需自行实现序列化逻辑(比如用
JsonUtility转成JSON,保存到PlayerPrefs或本地文件)。 - 不要尝试在运行时直接修改原始Scriptable Object资产,即使开启写入权限,也可能导致原始数据被意外修改,且这种修改在编辑器中是永久的,容易引发数据混乱。
内容的提问来源于stack exchange,提问作者moonkanghyuck
相关产品推荐
相关产品推荐

