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

Unity中自定义类列表加序列化特性仍不显示的问题

问题解决:Unity编辑器无法显示抽象类列表的原因与方案

核心问题出在Unity的序列化机制上:它默认不支持抽象类的多态序列化,哪怕你给抽象类和子类都加了[System.Serializable]、给列表加了[SerializeField]也没用——编辑器不知道该给这个列表实例化哪个具体的子类对象。

下面是几种可行的解决方案:


方案1:使用[SerializeReference](推荐,Unity 2019.3+适用)

Unity 2019.3版本引入了[SerializeReference]特性,专门用于支持多态类型的序列化。只需把列表上的[SerializeField]替换成这个特性即可:

修改SingleSpellManager.cs中的代码:

[System.Serializable]
public class SingleSpellManager 
{
    [SerializeReference] // 替换原有的[SerializeField]
    public List<ComponentClass> OnCast_Comp = new List<ComponentClass>();
    [SerializeReference]
    public List<ComponentClass> OnHit_Comp = new List<ComponentClass>();

    [Header ("General Data")]
    public string spellName;
}

注意事项:

  • 确保Unity版本在2019.3及以上
  • 抽象类ComponentClass和所有子类(比如Projectile)必须保留[System.Serializable]标记
  • 回到编辑器后,点击列表的"+"按钮,就能选择要添加的具体子类(如Projectile)

方案2:兼容旧版本Unity(无需[SerializeReference])

如果你的Unity版本低于2019.3,可以选择以下两种方式:

方式A:将抽象类改为普通类,用枚举标记类型

把ComponentClass改为非抽象类,添加枚举标识实例类型,后续在代码中根据类型区分逻辑:

[System.Serializable]
public enum ComponentType
{
    Projectile,
    // 可添加其他子类类型
}

[System.Serializable]
public class ComponentClass 
{
    public ComponentType type;
    
    public virtual void OnCast(){}
    public virtual void OnHit(){}

    // 原有通用字段...
}

[System.Serializable]
public class Projectile : ComponentClass
{
    public Projectile()
    {
        type = ComponentType.Projectile;
    }
    
    // 原有子类代码...
}

编辑器会正常显示列表,添加实例后手动选择类型,代码中根据type值执行对应逻辑即可。

方式B:用ScriptableObject存储组件实例

将每个ComponentClass子类改为ScriptableObject,列表存储ScriptableObject的引用:

// 把ComponentClass改为ScriptableObject基类
public abstract class ComponentClass : ScriptableObject
{
    public virtual void OnCast(){}
    public virtual void OnHit(){}

    // 原有通用字段...
}

[CreateAssetMenu(fileName = "Projectile", menuName = "Spell Components/Projectile")]
public class Projectile : ComponentClass
{
    // 原有子类代码...
}

修改SingleSpellManager的列表定义(保留[SerializeField]即可):

[System.Serializable]
public class SingleSpellManager 
{
    [SerializeField]
    public List<ComponentClass> OnCast_Comp = new List<ComponentClass>();
    // 其他代码...
}

这种方式需要先在Project窗口创建对应的ScriptableObject实例,再拖入列表,编辑器就能正常显示。


验证步骤

  1. 修改代码后回到Unity编辑器,等待脚本编译完成
  2. 选中挂载了SpellHolder的游戏对象,检查Inspector面板中List_Spells展开后,OnCast_Comp和OnHit_Comp是否正常显示
  3. 若使用方案1,点击列表"+"按钮应能看到可添加的子类选项

内容的提问来源于stack exchange,提问作者Gilang Agung

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 10:30:54