如何将类作为属性使用?实现类似Font属性的子属性可编辑需求
嘿,我太懂你说的这个需求了——就是想把自己写的类作为组件的属性,在Unity的Inspector(属性面板)里像内置的Font属性那样,能折叠展开直接编辑它的子属性对吧?我之前做UI系统的时候也纠结过这个,给你分享几个实用的解决办法:
方法1:给自定义类加
[Serializable]特性(最省心的基础方案) 这是最常用的操作,如果你只是想让一个普通的自定义类(不是继承自MonoBehaviour或ScriptableObject的那种)能在面板里展开编辑,只需要给类打上[Serializable]标记就行。举个例子:
// 给你的自定义类加上Serializable特性,告诉Unity可以序列化它 [Serializable] public class MyCustomFontStyle { public string displayText; public int fontSize; public Color textColor; public Font fontAsset; // 这里可以直接引用内置的Font类,和你说的效果呼应 } // 在你的业务脚本里把这个类作为属性使用 public class TextLabel : MonoBehaviour { // 现在这个属性会在Inspector里自动变成可折叠的面板,和Font属性一模一样 public MyCustomFontStyle labelStyle; }
这样写完之后,回到Unity编辑器,你就能看到labelStyle属性像Font那样可以折叠/展开,直接编辑里面的子字段了。
方法2:需要多态支持?用
[SerializeReference] 如果你的自定义类有继承关系(比如一个基类BaseStyle,子类ButtonStyle、TextStyle),想在面板里选择不同的子类实例,同时还能展开编辑子属性,那就要搭配[SerializeReference]特性:
[Serializable] public abstract class BaseStyle { } [Serializable] public class ButtonStyle : BaseStyle { public float buttonWidth; public Sprite buttonBg; } [Serializable] public class TextStyle : BaseStyle { public string content; public Font font; } public class UIManager : MonoBehaviour { // 用SerializeReference支持多态,同时保留展开编辑的功能 [SerializeReference] public BaseStyle currentStyle; }
这时在Inspector里,你可以右键点击currentStyle字段,选择创建不同的子类实例,每个实例的子属性都能像Font那样展开编辑,完美适配多态场景。
方法3:自定义编辑器(完全复刻Font的交互样式)
如果你想完全照搬Font属性的细节(比如带预览图、自定义折叠动画),可以用Unity的Editor API写自定义编辑器:
using UnityEditor; [CustomEditor(typeof(UIManager))] public class UIManagerEditor : Editor { // 记录折叠状态 private SerializedProperty _currentStyle; private bool _isStyleFolded = true; void OnEnable() { // 获取序列化的属性 _currentStyle = serializedObject.FindProperty("currentStyle"); } public override void OnInspectorGUI() { // 绘制折叠面板,和Font的样式对齐 _isStyleFolded = EditorGUILayout.Foldout(_isStyleFolded, "Current Style", true); if (_isStyleFolded) { EditorGUI.indentLevel++; // 绘制子属性 EditorGUILayout.PropertyField(_currentStyle, true); EditorGUI.indentLevel--; } // 绘制其他默认属性 serializedObject.ApplyModifiedProperties(); DrawDefaultInspector(); } }
这种方式可以完全自定义面板的交互逻辑和样式,和内置Font属性的表现完全一致。
几个要注意的小细节:
- 自定义类里的字段如果是私有/保护类型,要加上
[SerializeField]标记,Unity才能把它们显示在面板里。 - 如果你的类继承自ScriptableObject,直接创建ScriptableObject实例引用也能展开编辑,但那是外部引用式的,和内嵌序列化类的体验略有不同,根据你的需求选就行。
内容的提问来源于stack exchange,提问作者M4rsha11X
相关产品推荐
相关产品推荐

