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实例,再拖入列表,编辑器就能正常显示。
验证步骤
- 修改代码后回到Unity编辑器,等待脚本编译完成
- 选中挂载了
SpellHolder的游戏对象,检查Inspector面板中List_Spells展开后,OnCast_Comp和OnHit_Comp是否正常显示 - 若使用方案1,点击列表"+"按钮应能看到可添加的子类选项
内容的提问来源于stack exchange,提问作者Gilang Agung
相关产品推荐
相关产品推荐

