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;  // ← 需要
}
相关推荐
WMX10122 分钟前
Unity-shader学习记录
学习·unity·游戏引擎
WMX10127 分钟前
Hololens 2 上部署 Unity+MRTK 项目_模型着色
unity·游戏引擎·hololens
游乐码9 分钟前
unity基础(八)协程
游戏·unity·c#·游戏引擎
Codiggerworld11 分钟前
Neovim vs Vim:该不该“跳槽”?
编辑器·vim·跳槽
玉夏17 小时前
【Shader基础】ShaderLab 语法
unity·游戏引擎
玖玥拾18 小时前
Cocos学习笔记:自定义字体、骨骼动画与项目架构
游戏引擎·cocos2d
权、狐妖20 小时前
【Vscode安装ESlint插件、下载ESLint包以及他们之间的关系和使用】
ide·vscode·编辑器
玖玥拾21 小时前
Cocos学习笔记:渲染组件、摄像机系统与物理关节
游戏引擎·cocos2d
WarPigs21 小时前
Unity部署MessagePack
unity·游戏引擎
☆平常心☆1 天前
Unity插件MagicLightmapSwitcher修改灯光强度大于100
unity·游戏引擎