Unity泛型列表添加对象时类型不匹配问题排查
问题原因与解决方案
这个“Type mismatch”问题的根源在于Unity内置序列化系统对泛型ScriptableObject的泛型集合支持有局限。你的抽象泛型类RuntimeSet<T>里的public List<T> items字段,虽然在子类BuildingSet中指定了T=GameObject,但Unity的序列化引擎没法正确把这个泛型集合推断成List<GameObject>,导致编辑器渲染Inspector时出现类型不匹配的错误。
下面给你两种靠谱的解决办法,还有一个你代码里的小bug要提一下:
方法一:用抽象属性让子类提供具体类型集合
这个方法最直接,通过调整基类结构,让子类负责提供Unity能正确识别的具体类型集合:
- 修改泛型基类,把
items字段改成抽象属性,确保基类的Add/Remove方法能访问子类的具体集合:
public abstract class RuntimeSet<T> : ScriptableObject { // 定义抽象属性,由子类提供具体的集合实例 protected abstract List<T> Items { get; } public void Add(T t) { if (!Items.Contains(t)) { Items.Add(t); } } public void Remove(T t) { // 注意!你原来的Remove逻辑完全写反了,这里帮你修正了 if (Items.Contains(t)) { Items.Remove(t); } } }
- 在子类中实现这个属性,并声明具体类型的可序列化集合:
public class BuildingSet : RuntimeSet<GameObject> { [SerializeField] private List<GameObject> items = new List<GameObject>(); protected override List<GameObject> Items => items; }
这样Unity编辑器就能准确识别List<GameObject>类型,Inspector里的列表就能正常显示,不会再出现类型不匹配的提示了。
方法二:自定义Inspector编辑器(适合复杂场景)
如果不想改动基类的结构,可以给BuildingSet写个自定义编辑器,强制Unity正确识别字段类型:
using UnityEditor; using UnityEngine; [CustomEditor(typeof(BuildingSet))] public class BuildingSetEditor : Editor { private BuildingSet _target; private void OnEnable() { _target = (BuildingSet)target; } public override void OnInspectorGUI() { // 手动序列化并绘制items列表 serializedObject.Update(); SerializedProperty itemsProp = serializedObject.FindProperty("items"); EditorGUILayout.PropertyField(itemsProp, true); serializedObject.ApplyModifiedProperties(); // 可以额外加一些便捷功能,比如一键添加选中的GameObject if (GUILayout.Button("Add Selected GameObject")) { if (Selection.activeGameObject != null) { _target.Add(Selection.activeGameObject); } } } }
额外提醒:你的Remove方法有逻辑错误
原来的代码里,Remove方法的判断条件是if (!items.Contains(t))——这意味着只有当列表没有这个元素的时候才去移除,完全搞反了!这样永远没法移除已经存在的元素,一定要改成if (items.Contains(t))才行。
内容的提问来源于stack exchange,提问作者Green_qaue
相关产品推荐
相关产品推荐

