You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity构建后如何修改ScriptableObject内容?值无法变更的解决方法

Unity构建后ScriptableObject int值无法修改的原因与解决方法

可能的原因

  • 原始SO资产被打包为只读资源:构建时Unity会将Assets目录下的ScriptableObject文件打包成只读资源,运行时直接读取原始文件的副本,修改操作仅在内存中临时生效,重启exe后会恢复初始值;若代码直接引用原始SO资产而非运行时实例,修改不会被持久化或实际生效。
  • 字段序列化或权限问题:int字段若为private且未标记[SerializeField],或构建时Unity因代码优化误判字段未被使用,会导致字段被剥离或序列化异常,进而无法修改。
  • 静态引用/单例实现错误:通过静态方式直接引用原始SO资产,构建后资源加载机制变化,修改的是只读的原始实例,而非可读写的运行时副本。

解决方法

方法1:运行时创建SO实例

不要直接修改原始SO资产,通过ScriptableObject.CreateInstance<T>()创建运行时实例,修改该实例的字段即可正常生效:

// 假设你的SO类型为MyScriptableObject
MyScriptableObject runtimeSO = ScriptableObject.CreateInstance<MyScriptableObject>();
runtimeSO.targetInt = 100; // 修改操作正常生效

若需要保留原始SO的初始数据,可先加载原始资产再复制字段:

MyScriptableObject originalSO = Resources.Load<MyScriptableObject>("Assets/Path/To/YourSO");
MyScriptableObject runtimeSO = ScriptableObject.CreateInstance<MyScriptableObject>();
runtimeSO.targetInt = originalSO.targetInt;
// 后续修改runtimeSO的字段即可

方法2:将SO数据持久化到外部文件

如果需要保存修改后的数据,可将SO字段序列化为JSON/XML等格式写入外部文件,运行时先读取文件覆盖字段值,修改后再写入:

// 保存数据
string jsonData = JsonUtility.ToJson(runtimeSO);
File.WriteAllText(Application.persistentDataPath + "/SOData.json", jsonData);

// 加载数据
string savePath = Application.persistentDataPath + "/SOData.json";
if (File.Exists(savePath))
{
    string jsonData = File.ReadAllText(savePath);
    JsonUtility.FromJsonOverwrite(jsonData, runtimeSO);
}

注意:需结合方法1使用运行时创建的实例,避免修改只读的原始资产。

方法3:检查字段序列化配置

确保int字段的序列化配置正确,避免被构建优化剥离:

[CreateAssetMenu(fileName = "New MySO", menuName = "Custom/MyScriptableObject")]
public class MyScriptableObject : ScriptableObject
{
    [SerializeField] // 私有字段需添加该标签确保序列化
    private int targetInt;
    // 或直接使用public字段,默认支持序列化
    // public int targetInt;
}

同时关闭PlayerSettings中的无用代码剥离选项:

  • 打开Edit > Project Settings > Player > Other Settings
  • 找到Optimization下的Strip unused code,取消勾选(或降低剥离等级)

方法4:用Addressables加载可修改实例

使用Addressables管理SO时,将加载模式设为Instantiate,获取原始资产的可修改副本:

  • 在Addressables Groups窗口选中目标SO资产
  • 在Inspector的Addressable Asset Settings中,将Load Type设为Instantiate
  • 加载时调用Addressables.InstantiateAsync<MyScriptableObject>("your-so-address")获取可修改实例

内容的提问来源于stack exchange,提问作者맹주영

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 01:50:33