Unity编辑器脚本问题:Sprite数组可视化编辑失效如何解决?
解决方法
要实现可编辑的可视化Sprite字段,需要解决赋值同步和修改持久化两个核心问题,同时优化代码结构。以下是具体修改方案:
1. 调整SkinData脚本(可选)
如果不想让原生数组在Inspector中显示,可添加[HideInInspector]属性隐藏默认数组视图:
public class SkinData : ScriptableObject { [HideInInspector] public Sprite[] FaceDownSprites = new Sprite[MaxFrameCount]; }
2. 重写自定义Editor脚本
修改后的脚本支持拖拽赋值、Undo操作,且修改会同步保存:
[CustomEditor(typeof(SkinData))] public class SkinDataEditor : UnityEditor.Editor { private const float SpriteFieldSize = 100f; public override void OnInspectorGUI() { // 若已隐藏原生数组,注释掉此行,避免显示默认数组 // base.OnInspectorGUI(); SkinData skinData = (SkinData)target; GUILayout.Label("Tilesheet", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); // 遍历数组实现批量处理,适配任意长度的Sprite数组 for (int i = 0; i < skinData.FaceDownSprites.Length; i++) { // 接收ObjectField返回的新Sprite,实现赋值同步 var newSprite = (Sprite)EditorGUILayout.ObjectField( skinData.FaceDownSprites[i], typeof(Sprite), false, // 禁止引用Scene对象,避免ScriptableObject引用丢失 GUILayout.Height(SpriteFieldSize), GUILayout.Width(SpriteFieldSize) ); // 仅当值变化时记录操作,减少不必要的Undo开销 if (newSprite != skinData.FaceDownSprites[i]) { // 记录Undo操作,支持撤销 Undo.RecordObject(skinData, $"Update FaceDown Sprite {i}"); skinData.FaceDownSprites[i] = newSprite; // 标记对象为脏数据,确保修改被持久化到磁盘 EditorUtility.SetDirty(skinData); } } EditorGUILayout.EndHorizontal(); } }
关键修改点说明
- 接收ObjectField返回值:原代码仅显示Sprite,未将用户拖拽的新对象赋值回数组,修改后通过接收返回值完成同步。
- Undo与脏数据标记:
Undo.RecordObject支持撤销操作,EditorUtility.SetDirty通知Unity保存修改,解决了修改无法持久化的问题。 - 遍历数组替代硬编码:用循环处理数组元素,代码更灵活,无需在数组长度变化时修改Editor脚本。
- 禁止Scene对象引用:ScriptableObject不能保存Scene对象引用,通过
ObjectField的第四个参数false限制输入类型,避免引用丢失。
内容的提问来源于stack exchange,提问作者Michał Lorenc
相关产品推荐
相关产品推荐

