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

ScriptableObject修改在Git客户端本地变更中不显示的问题求助

问题分析与解决方案

问题场景

我有两个ScriptableObject定义如下:

TestScriptableObject.cs

using System;
using Sirenix.OdinInspector;
using UnityEngine;

[CreateAssetMenu(fileName = "TestScriptableObject", menuName = "ScriptableObject/TestScriptableObject")]
public class TestScriptableObject : ScriptableObject
{
    public string currentTime;
        
    [Button]
    public void Change()
    {
        currentTime = DateTime.Now.ToString("u");
    }
}

TestScriptableObject2.cs

using Sirenix.OdinInspector;
using UnityEngine;

namespace JimmyTest
{
    [CreateAssetMenu(fileName = "TestScriptableObject2", menuName = "ScriptableObject/TestScriptableObject2")]
    public class TestScriptableObject2 : ScriptableObject
    {
        public string currentTime;
        public TestScriptableObject TestScriptableObject;
        
        [Button]
        private void Change()
        {
            TestScriptableObject.Change();
        }
    }
}

直接点击TestScriptableObject.asset的按钮修改值时,Git能识别本地变更;但点击TestScriptableObject2.asset的按钮(通过关联对象修改值)时,Git Fork无法显示该变更。

原因

问题出在Unity没有将被修改的TestScriptableObject标记为"脏对象",导致Unity没有把内存中的修改写入磁盘。直接在自身按钮方法修改时,Odin Inspector或Unity Editor的按钮逻辑会自动标记脏对象,但通过其他SO间接调用时,这个自动标记逻辑未触发,磁盘上的.asset文件没更新,Git自然检测不到变化。

解决方案

在TestScriptableObject的Change方法中,手动标记对象为脏并触发资产保存:

方案1(推荐,符合Unity新API规范且支持撤销)

using System;
using Sirenix.OdinInspector;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

[CreateAssetMenu(fileName = "TestScriptableObject", menuName = "ScriptableObject/TestScriptableObject")]
public class TestScriptableObject : ScriptableObject
{
    public string currentTime;
        
    [Button]
    public void Change()
    {
#if UNITY_EDITOR
        // 记录对象状态,标记为脏同时支持撤销操作
        Undo.RecordObject(this, "Update Current Time");
#endif
        currentTime = DateTime.Now.ToString("u");
        
#if UNITY_EDITOR
        // 强制将脏资产写入磁盘
        AssetDatabase.SaveAssets();
#endif
    }
}

方案2(兼容旧版本Unity,API已过时)

如果使用Unity 2020.1之前的版本,可以用EditorUtility.SetDirty替代Undo.RecordObject:

#if UNITY_EDITOR
EditorUtility.SetDirty(this);
#endif

说明

  • Undo.RecordObject是Unity推荐的Editor修改对象的方式,既标记对象为脏,还支持Editor内的撤销操作。
  • AssetDatabase.SaveAssets会将所有标记为脏的资产同步到磁盘,确保Git能检测到文件变更。
  • 用#if UNITY_EDITOR包裹Editor相关代码,避免打包时出现编译错误。

内容的提问来源于stack exchange,提问作者JAMONGJJ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:17:05