Unity 编辑器扩展

复制代码
[CustomEditor(typeof(XXXConfig))]
public class XXXConfigEditor : UnityEditor.Editor

这是一个 属性标签(Attribute),告诉 Unity:

"当用户在 Inspector 中选中一个 XXXConfig 类型的 ScriptableObject 资产时,不要用默认的 Inspector,而是用我写的 XXXConfigEditor 来渲染面板。"

复制代码
用户在 Hierarchy/Project 中选中 XXXConfig 资产
    ↓
Unity 检测到 [CustomEditor(typeof(XXXConfig))]
    ↓
实例化 XXXConfigEditor
    ↓
调用 OnInspectorGUI() 方法(你必须重写这个方法)
    ↓
你在 OnInspectorGUI() 里用 GUILayout/EditorGUILayout 绘制自定义控件
    ↓
用户点击按钮、修改字段 → 通过 serializedObject.ApplyModifiedProperties() 保存修改

serializedObject 是继承自 UnityEditor.Editor 基类的内置属性

复制代码
public class XXXConfigEditor : UnityEditor.Editor  // 继承了 Editor
{
    // serializedObject 来自父类 UnityEditor.Editor
    // 你不需要声明,直接用就行
}

serializedObjectSerializedObject 类型 ,它是你正在编辑的目标资产(即 TutorialConfig 实例)的序列化包装器

核心作用

作用 说明
读取字段 通过 serializedObject.FindProperty("fieldName") 访问资产里的字段
修改字段 通过 property.intValue = xxx 修改值
保存修改 调用 serializedObject.ApplyModifiedProperties() 把修改写入磁盘
撤销支持 配合 Undo.RecordObject() 实现 Ctrl+Z 撤销
多对象编辑 同时选中多个资产时,自动处理共有的可编辑字段
复制代码
public override void OnInspectorGUI()
{
    // 1. 更新序列化对象(从磁盘读取最新状态)
    serializedObject.Update();

    // 2. 获取字段
    SerializedProperty xxList = serializedObject.FindProperty("lists");

    // 3. 绘制字段(Unity 自动处理 UI)
    EditorGUILayout.PropertyField(xxList);

    // 4. 应用修改(保存回资产文件)
    serializedObject.ApplyModifiedProperties();
}

ReorderableList 是 Unity 编辑器内置的可拖拽排序列表控件,专门用于在 Inspector 中展示和操作数组/列表。

复制代码
using UnityEditorInternal;  // 命名空间

ReorderableList list = new ReorderableList(serializedObject, property);

它提供了一个可视化的列表 UI,支持:

功能 说明
拖拽排序 鼠标拖拽元素上下移动
添加/删除 右侧有 + - 按钮
折叠/展开 点击左侧箭头展开子字段
多选 支持框选多个元素批量操作
自定义绘制 可以重写回调方法自定义每个元素的显示
复制代码
var dropdown = new StageTypeDropdown(_dropdownState, onSelected);
dropdown.Show(buttonRect); 


当执行 dropdown.Show(buttonRect) 时,Unity 内部的 AdvancedDropdown 会:
弹出下拉框窗口
立即调用 BuildRoot() 构建下拉框的内容树
渲染树节点显示给用户


用户点击 ReorderableList 的 + 按钮
    ↓
onAddDropdownCallback 触发
    ↓
StageTypeSelector.Show(buttonRect, OnStageTypeSelected)
    ↓
new StageTypeDropdown(...)  // 创建实例
    ↓
dropdown.Show(buttonRect)   // 显示下拉框
    ↓
[Unity 内部] AdvancedDropdown.Show()
    ↓
[Unity 内部] 调用 BuildRoot()  ← 你的重写方法在这里被调用
    ↓
返回 AdvancedDropdownItem 根节点
    ↓
渲染下拉框内容

[SerializeReference]

复制代码
    [Serializable]
    public abstract class BaseType
    {
        [SerializeField] private string _typeName= "xxx";
    }

// ❌ 默认序列化:只保存基类字段,丢失子类信息
public List<BaseType> BaseTypes;  

// ✅ 使用 SerializeReference:保存实际类型 + 子类字段
[SerializeReference]
public List<BaseType> BaseTypes; 
默认序列化 [SerializeReference]
序列化时 只保存基类 Stage 的字段 保存实际类型 + 所有字段
反序列化后 变成 Stage(基类) 还原为 FocusSampleStage(子类)
子类字段 丢失 完整保留
null 值 不允许(总是创建实例) 允许 null
多态引用 不支持 支持
复制代码
// ✅ 接口
[SerializeReference] public ITrigger Trigger;

// ✅ 抽象类
[SerializeReference] public Stage CurrentStage;

// ✅ 数组/列表
[SerializeReference] public List<Stage> Stages;

// ❌ 不能用在值类型(struct、int、Color 等)
[SerializeReference] public int Value;  // 编译报错

// ❌ 不能用在继承自 MonoBehaviour/ScriptableObject 的类
[SerializeReference] public MyMonoBehaviour Ref;  // 运行时报错

// ❌ 不能用在 GameObject/Transform 等 Unity 原生对象
[SerializeReference] public GameObject Go;  // 不生效

子类必须标注 [Serializable]
[Serializable]  // ← 必须!
public class TestTypes : BaseType
{
    [SerializeField] private float _animationDuration;
}


字段本身不需要再加 [SerializeField]

// [SerializeReference] 本身就表示"参与序列化",不需要 [SerializeField]
[SerializeReference] public List<BaseType> baseTypes;

// 但子类内部的字段仍然需要 [SerializeField]
[Serializable]
public class TestTypes: BaseType
{
    [SerializeField] private float _duration;  // ← 需要
}
相关推荐
VidDown3 天前
VidDown 工具站:免费、本地优先的开发者工具箱
javascript·编辑器·音视频·视频编解码·视频
VidDown3 天前
显卡处理视频技术详解:从硬解码到 NVENC,GPU 如何让视频处理起飞?
javascript·编辑器·音视频·视频编解码·视频
夜猫逐梦3 天前
【UE基础】03.蓝图与编辑器工作流
编辑器·ue·蓝图·ue编辑器
VidDown3 天前
视频帧率技术详解:从 24fps 到 120fps,帧率如何影响你的观看体验?
网络·网络协议·编辑器·音视频·视频编解码·视频
叶帆3 天前
【YFIOs】用C#开发硬件之设备上云
开发语言·unity·c#
爱就是恒久忍耐3 天前
VSCode里如何比较2个branch
ide·vscode·编辑器
久数君3 天前
AI三维建模工具“造形家”:地理场景三维化的高效解决方案
unity·glb·ai算法·ai三维建模工具·地图框选·造形家·城市建筑模型
bloglin999993 天前
vscode中可视化的合并分支,在“合并编辑器中解析”中“与基线进行比较”是什么意思
ide·vscode·编辑器
会思考的猴子4 天前
Unity VFX 属性 Postion 和 TargetPostion
unity
zyplayer-doc4 天前
企业知识库安全与权限管理完全指南:从加密到审计的六层防护
人工智能·安全·pdf·编辑器·创业创新