当前位置: 首页 > news >正文

第三章自定义检视面板_创建自定义编辑器类_检测与应用修改(本章进度(2/9))

3.1创建自定义编辑器类

3.1.2检测与应用修改

上一节通过在Inspecotor修改字段时,会直接赋值给字段,但是其他字段没有修改也会被重新赋值一下,对性能有一定影响,所以我们可以通过检测Inspecotor变更时候,才对字段修改。
代码示例

using System.Reflection; // 引入反射命名空间,用于访问私有字段
using UnityEditor;       
using UnityEngine;     /// <summary>
/// 使用CustomEditor特性,指定这个编辑器类是为CustomComponent组件服务的
/// </summary>
[CustomEditor(typeof(CustomComponent))]
public class CustomCompoentEditor : Editor
{private CustomComponent component; // 当前正在编辑的CustomComponent组件实例// 序列化属性,用于访问和修改组件中的序列化字段private SerializedProperty stringValueProperty; // 字符串类型字段private SerializedProperty gameObjectProperty;  // GameObject类型字段private SerializedProperty enumValue;           // 枚举类型字段// 反射字段信息,用于访问私有字段private FieldInfo boolValueFieldInfo; // 布尔类型私有字段// 当编辑器启用时调用,用于初始化private void OnEnable(){/*这里只是为了演示不同的获取方式 一种当字段是public时可以直接访问,或者被[serilaredField]*///工作原理就是从target中获取到当前正在编辑的组件实例,然后去查找指定字段// 获取当前正在编辑的组件实例component = (CustomComponent)target;// 通过序列化对象查找并获取各个序列化属性stringValueProperty = serializedObject.FindProperty("stringValue"); // 查找字符串字段,这里不是反射,是unituy序列化系统gameObjectProperty = serializedObject.FindProperty("go");           // 查找GameObject字段enumValue = serializedObject.FindProperty("exampleEnum");           // 查找枚举字段// 初始化反射字段boolValueFieldInfo = component.GetType().GetField("boolValue",BindingFlags.NonPublic | BindingFlags.Instance);}/// <summary>/// 重写OnInspectorGUI方法,自定义Inspector界面/// </summary>public override void OnInspectorGUI(){// base.OnInspectorGUI(); // 如果取消注释,会显示默认的Inspector界面ChangeCheckExample();}/// <summary>/// 变化检测示例/// </summary>private void ChangeCheckExample(){// 1. 使用 EditorGUI.BeginChangeCheck() 检测整数字段变化EditorGUI.BeginChangeCheck();component.intValue = EditorGUILayout.IntField("整数", component.intValue);// 如果检测到变更,返回为trueif (EditorGUI.EndChangeCheck()){Debug.Log("整数发生变更");}// 2. 处理字符串字段(使用序列化属性)// private修饰的字段 通过序列化属性的方式访问和修改其值string newStringValue = EditorGUILayout.TextField("字符串", stringValueProperty.stringValue);// 对比是否不一致,不一致则更新if (newStringValue != stringValueProperty.stringValue){stringValueProperty.stringValue = newStringValue;Debug.Log("StringValue 发生变化");}// 3. 处理布尔字段(使用反射)// private修饰的字段 通过反射的方式访问和修改其值boolValueFieldInfo.SetValue(component,EditorGUILayout.Toggle("Bool Value",(bool)boolValueFieldInfo.GetValue(component)));// 4. 绘制GameObject字段(使用序列化属性)EditorGUILayout.PropertyField(gameObjectProperty);// 5. 处理枚举字段(使用序列化属性)enumValue.enumValueIndex = EditorGUILayout.Popup("枚举值",enumValue.enumValueIndex,enumValue.enumNames);// 6. 检测整体GUI变化if (GUI.changed){Debug.Log("GUI发生了变更");}}}

在这里插入图片描述

3.完成了字段获取和修改,我们接下来就是对字段的保存。但是下面的代码实际上不会立刻保存,他只是标记保存,当我们保存场景或者项目的时候,才会保存。具体逻辑和代码如下图

在这里插入图片描述
示例代码

using System.Reflection; // 引入反射命名空间,用于访问私有字段
using UnityEditor;       
using UnityEngine;     /// <summary>
/// 使用CustomEditor特性,指定这个编辑器类是为CustomComponent组件服务的
/// </summary>
[CustomEditor(typeof(CustomComponent))]
public class CustomCompoentEditor : Editor
{private CustomComponent component; // 当前正在编辑的CustomComponent组件实例// 序列化属性,用于访问和修改组件中的序列化字段private SerializedProperty stringValueProperty; // 字符串类型字段private SerializedProperty gameObjectProperty;  // GameObject类型字段private SerializedProperty enumValue;           // 枚举类型字段// 反射字段信息,用于访问私有字段private FieldInfo boolValueFieldInfo; // 布尔类型私有字段// 当编辑器启用时调用,用于初始化private void OnEnable(){/*这里只是为了演示不同的获取方式 一种当字段是public时可以直接访问,或者被[serilaredField]*///工作原理就是从target中获取到当前正在编辑的组件实例,然后去查找指定字段// 获取当前正在编辑的组件实例component = (CustomComponent)target;// 通过序列化对象查找并获取各个序列化属性stringValueProperty = serializedObject.FindProperty("stringValue"); // 查找字符串字段,这里不是反射,是unituy序列化系统gameObjectProperty = serializedObject.FindProperty("go");           // 查找GameObject字段enumValue = serializedObject.FindProperty("exampleEnum");           // 查找枚举字段// 初始化反射字段boolValueFieldInfo = component.GetType().GetField("boolValue",BindingFlags.NonPublic | BindingFlags.Instance);}/// <summary>/// 重写OnInspectorGUI方法,自定义Inspector界面/// </summary>public override void OnInspectorGUI(){// base.OnInspectorGUI(); // 如果取消注释,会显示默认的Inspector界面ApplyModificationExample();}private void ApplyModificationExample(){// 公共字段(public)可以直接访问和修改// 创建一个整数输入框,显示并允许修改组件的 intValue 字段component.intValue = EditorGUILayout.IntField("Int Value", component.intValue);// 私有字段(private)通过序列化属性(SerializedProperty)访问和修改// 创建一个文本输入框,显示并允许修改组件的 stringValue 字段stringValueProperty.stringValue = EditorGUILayout.TextField("String Value", stringValueProperty.stringValue);// 私有字段(private)通过反射(FieldInfo)访问和修改// 创建一个布尔开关(Toggle),显示并允许修改组件的 boolValue 字段boolValueFieldInfo.SetValue(component, EditorGUILayout.Toggle("Bool Value", (bool)boolValueFieldInfo.GetValue(component)));// 使用 PropertyField 绘制 GameObject 类型的字段// 这种方式更通用,能自动处理多种类型的字段显示EditorGUILayout.PropertyField(gameObjectProperty);// 使用 Popup 下拉框显示并允许修改枚举类型的字段enumValue.enumValueIndex = EditorGUILayout.Popup("Enum Value", enumValue.enumValueIndex, enumValue.enumNames);// 检测是否有任何控件发生了变更if (GUI.changed){// 应用所有通过 SerializedProperty 修改的字段到组件实例中// 注意:只保存通过 serializedObject.FindProperty 获得的字段// 不保存通过反射(FieldInfo)获得的字段serializedObject.ApplyModifiedProperties();// 手动标记组件为“脏”(Dirty)// 因为通过反射(FieldInfo)修改的字段不会被 Unity 自动标记为脏,//我们为了演示反射,我们自定义类CustomComponent 里的go 是通过反射拿到的,所以这里要手动标记组件为脏// 所谓“脏”就是告诉 Unity:“这个组件的数据被修改了,保存时需要包含它”EditorUtility.SetDirty(component);}}}
http://www.lryc.cn/news/592041.html

相关文章:

  • Xilinx Zynq:一款适用于软件定义无线电的现代片上系统
  • 深度学习之----对抗生成网络-pytorch-CycleGAN-and-pix2pix
  • IP协议深入理解
  • RustDesk 自建中继服务器教程(Mac mini)
  • 蓝松抠图的几大优点.
  • Vue中的refs字段使用记录
  • (数据结构)线性表(上):SeqList 顺序表
  • k8s:利用kubectl部署postgis:17-3.5
  • Kotlin序列
  • CloudFabric解决方案
  • 【怜渠客】简单实现手机云控Windows电脑锁屏
  • HTTP 性能优化:五条建议
  • 线程安全集合——ConcurrentHashMap
  • 微店平台商品详情接口技术实现指南
  • 前端埋坑之js console.log字符换行后 html没换行问题处理
  • javascript 中数组对象操作方法
  • AE PDW2200电源射频手侧使用安装说明含电路图
  • 自学力扣:最长连续序列
  • CSS样式中的布局、字体、响应式布局
  • AI大模型打造金融智能信审助手04.七大金融监管相关政策
  • 【Oracle】centos7离线静默安装oracle11g(p13390677_112040)
  • 智象科技赋能金融、证券行业 IT 运维
  • PostgreSQL 16 Administration Cookbook 读书笔记:第7章 Database Administration
  • 【git仓库搭建笔记】
  • Oracle 19C 后台主要进程的功能解析
  • CertiK创始人顾荣辉出席上海Conflux大会,聚焦Web3全球化中的安全与合规路径
  • 赛思SLIC芯片、语音芯片原厂 赛思SLIC语音芯片ASX630:国产强“芯”赋能FTTR全光网络​
  • Docker Swarm 集群使用记录
  • 基于LiteNetLib的Server/Client Demo
  • 算法训练营day24 回溯算法③ 93.复原IP地址 、78.子集、 90.子集II