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

如何将类作为属性使用?实现类似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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:11:44