Unity 2020.2.1f1 Editor脚本修改参数Play模式后重置问题
问题根因
你确实遗漏了Unity Editor修改序列化对象的必要持久化标记操作,同时如果操作对象是Prefab本体,还需要补充Prefab资产的写入逻辑:
- 直接在Editor脚本中修改
target的字段,仅会改动内存中的临时值,不会触发Unity的序列化保存流程。你在编辑模式下看到的字段数值变化,只是Inspector UI对内存值的即时刷新,并没有真正写入到场景/Prefab的持久化文件中。 - 切换到Play模式时,Unity会自动将所有非运行时修改的对象状态,重置为已持久化的编辑模式默认值;退出Play模式后也会回滚到这个已保存的状态,因此你未持久化的修改会直接丢失。
修复步骤
1. 核心修复:标记对象为需要持久化
在修改完objID字段后,必须调用EditorUtility.SetDirty(),告知Unity该对象存在需要序列化保存的修改:
public void GenerateID(StateObject s) { s.objID = DateTimeOffset.Now.ToUnixTimeSeconds(); // 新增这行核心标记 EditorUtility.SetDirty(s); }
这一步处理后:
- 如果
StateObject是场景内的对象,后续你手动保存场景时,这个修改就会被永久写入场景文件 - 如果
StateObject是Prefab的场景实例,这个修改会被标记为Prefab实例的覆写属性,保存场景后也会持久生效
2. 特殊场景:操作Prefab资产本体时的额外处理
如果你的StateObject是直接挂在Prefab资产本体(不是场景里的实例)上,仅调用SetDirty只会把改动标记为待保存,需要额外调用Prefab的保存接口,才能把改动直接写入Prefab文件:
public void GenerateID(StateObject s) { s.objID = DateTimeOffset.Now.ToUnixTimeSeconds(); EditorUtility.SetDirty(s); // 判断当前对象是否属于Prefab资产本体,是则直接保存改动 if (PrefabUtility.IsPartOfPrefabAsset(s)) { PrefabUtility.SaveAsPrefabAsset(s.gameObject, AssetDatabase.GetAssetPath(s)); } }
3. 体验优化:让修改支持撤销操作
按照Unity Editor的操作规范,修改对象状态前需要包裹Undo接口,让这个生成ID的操作支持Ctrl+Z撤销:
public override void OnInspectorGUI() { DrawDefaultInspector(); StateObject s = (StateObject)target; if (s.objID == 0) { if (GUILayout.Button("Generate Object ID")) { GenerateID(s); } } } public void GenerateID(StateObject s) { // 新增撤销记录,操作可被撤销 Undo.RecordObject(s, "Generate State Object ID"); s.objID = DateTimeOffset.Now.ToUnixTimeSeconds(); EditorUtility.SetDirty(s); // Prefab资产的特殊保存逻辑 if (PrefabUtility.IsPartOfPrefabAsset(s)) { PrefabUtility.SaveAsPrefabAsset(s.gameObject, AssetDatabase.GetAssetPath(s)); } }
注意:Play模式下对对象的修改本身就是临时运行时状态,默认就不会持久化。一般生成objID的逻辑只需要在编辑模式下执行即可,不需要额外处理Play模式下的修改。
内容的提问来源于stack exchange,提问作者basklein
相关产品推荐
相关产品推荐

