Unity Inspector中列表更新异常,报错‘type is not a supported string value’
问题分析
这个错误是Unity编辑器Retained Mode序列化系统与你修改ScriptableObject序列化列表的操作冲突导致的。当List<InventoryItem>在Inspector中显示时,编辑器会持续追踪其序列化状态,直接修改字段会打破编辑器的序列化预期,触发类型解析错误。
解决方案
1. 让编辑器追踪ScriptableObject的修改
在修改ItemsInInventory前,通过Undo.RecordObject让编辑器记录操作,确保序列化系统能正确处理变更:
修改SO_Inventory的UpdateInventory方法:
public void UpdateInventory() { #if UNITY_EDITOR // 编辑器模式下记录操作,避免序列化冲突 if (!Application.isPlaying) { UnityEditor.Undo.RecordObject(this, "Update Inventory"); } #endif int randomNumber = Random.Range(0, GameAssets.instance.Items.Length); InventoryItem itemToAdd = new InventoryItem { Item = GameAssets.instance.Items[randomNumber], Amount = 3 }; // 原有逻辑不变... }
2. 将ItemObject改为ScriptableObject
普通[Serializable]类作为引用嵌套在ScriptableObject中时,Unity编辑器的序列化稳定性较差。改为ScriptableObject实例引用能解决这类序列化问题:
修改ItemObject
using UnityEngine; [CreateAssetMenu(fileName = "New Item", menuName = "Inventory/Item")] public class ItemObject : ScriptableObject { public int ItemID; public string ItemName; [Range(1, 64)] public int MaxStack = 8; }
调整GameAssets中的赋值逻辑
将OnValidate中的AssignItemIDs移到运行时执行,避免编辑器模式下修改序列化字段:
public class GameAssets : MonoBehaviour { public ItemObject[] Items; private void Awake() { AssignItemIDs(); } private void AssignItemIDs() { for (int i = 0; i < Items.Length; i++) { Items[i].ItemID = i; } } }
3. 自定义Inspector绘制逻辑
通过自定义Editor手动控制SO_Inventory的Inspector显示,绕过Unity默认的序列化绘制逻辑:
创建SO_InventoryEditor.cs:
using UnityEngine; using UnityEditor; [CustomEditor(typeof(SO_Inventory))] public class SO_InventoryEditor : Editor { public override void OnInspectorGUI() { serializedObject.Update(); // 绘制可用槽位 EditorGUILayout.PropertyField(serializedObject.FindProperty("AvailableSlots")); // 手动绘制物品列表 var itemsProp = serializedObject.FindProperty("ItemsInInventory"); EditorGUILayout.PropertyField(itemsProp, true); // 添加测试按钮 if (GUILayout.Button("Update Inventory")) { var inventory = (SO_Inventory)target; inventory.UpdateInventory(); EditorUtility.SetDirty(inventory); } serializedObject.ApplyModifiedProperties(); } }
4. 限制仅在运行时执行更新逻辑
如果不需要在编辑器模式下测试UpdateInventory,可以直接限制该方法仅在运行时执行:
public void UpdateInventory() { if (!Application.isPlaying) return; // 原有逻辑不变... }
内容的提问来源于stack exchange,提问作者Luis Enrique Cendejas Sosa
相关产品推荐
相关产品推荐

