Unity编辑器中如何显示带自定义setter的枚举属性?
解决方案:Unity编辑器中显示枚举属性并触发Setter方法
问题根源说明
你当前的代码存在两个关键问题:
- Unity原生编辑器对**自动属性(auto-property)**的序列化支持有限,
[field: SerializeField]虽会生成序列化字段,但编辑器不会展示对应的属性编辑界面; - 属性的
get和set直接访问属性本身(get => ball),会触发无限递归导致栈溢出,必须改用私有字段存储值。
以下提供两种可行方案,覆盖原生Unity实现和Odin插件优化路径:
一、原生Unity实现(无需插件)
通过「私有序列化字段 + 公共属性」的组合,配合OnValidate方法确保编辑器修改值时触发逻辑:
public enum Balls { BaseBall, Basketball, Football } // 私有字段用于序列化,编辑器自动生成枚举下拉菜单 [SerializeField] private Balls _ball; // 公共属性供代码调用,setter中触发图标更新逻辑 public Balls Ball { get => _ball; set { _ball = value; SetIcon(value); } } // Unity编辑器修改字段值时自动调用该方法 private void OnValidate() { // 确保编辑器中修改值后同步更新图标 SetIcon(_ball); } private void SetIcon(Balls ballType) { // 你的图标渲染逻辑 }
核心逻辑:
[SerializeField]标记私有字段_ball,编辑器会自动生成枚举下拉选择界面;OnValidate是Unity编辑器专属生命周期方法,修改任何序列化字段值时都会触发,保证界面操作能同步执行SetIcon;- 外部代码通过公共属性
Ball赋值时,直接走setter触发逻辑。
二、Odin插件优化实现(更简洁)
Odin插件对属性序列化和编辑器交互支持更完善,能直接显示公共属性并保证setter被触发,还可通过特性简化逻辑:
方案1:属性+Setter直接触发
using Sirenix.OdinInspector; public enum Balls { BaseBall, Basketball, Football } // Odin会在编辑器中生成该属性的下拉菜单 [ShowInInspector] public Balls Ball { get => _ball; set { _ball = value; SetIcon(value); } } // 私有字段存储值,无需加SerializeField(Odin自动处理序列化) private Balls _ball; private void SetIcon(Balls ballType) { // 你的图标渲染逻辑 }
方案2:用OnValueChanged特性分离逻辑
如果不想在setter中耦合业务逻辑,可通过Odin的OnValueChanged特性直接绑定触发方法:
using Sirenix.OdinInspector; public enum Balls { BaseBall, Basketball, Football } [ShowInInspector] [OnValueChanged(nameof(OnBallChanged))] // 值变化时自动调用指定方法 public Balls Ball { get; set; } private void OnBallChanged() { SetIcon(Ball); } private void SetIcon(Balls ballType) { // 你的图标渲染逻辑 }
核心逻辑:
[ShowInInspector]让Odin在编辑器中生成属性的下拉选择界面;- 修改属性值时,Odin会自动调用属性的setter(方案1)或绑定的
OnValueChanged方法(方案2),确保SetIcon被触发; - 无需手动处理序列化字段,代码结构更简洁。
内容的提问来源于stack exchange,提问作者Todd Davis
相关产品推荐
相关产品推荐

