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

Unity泛型列表添加对象时类型不匹配问题排查

问题原因与解决方案

这个“Type mismatch”问题的根源在于Unity内置序列化系统对泛型ScriptableObject的泛型集合支持有局限。你的抽象泛型类RuntimeSet<T>里的public List<T> items字段,虽然在子类BuildingSet中指定了T=GameObject,但Unity的序列化引擎没法正确把这个泛型集合推断成List<GameObject>,导致编辑器渲染Inspector时出现类型不匹配的错误。

下面给你两种靠谱的解决办法,还有一个你代码里的小bug要提一下:

方法一:用抽象属性让子类提供具体类型集合

这个方法最直接,通过调整基类结构,让子类负责提供Unity能正确识别的具体类型集合:

  1. 修改泛型基类,把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);
        }
    }
}
  1. 在子类中实现这个属性,并声明具体类型的可序列化集合:
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:20:55