当前位置: 首页 > 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.dtcms.com/a/286054.html

相关文章:

  • 可靠消息最终一致性分布式事务解决方案
  • 补贴退坡、平价上网,数字隔离器如何守护更高功率的光伏逆变器?
  • 门控线性单元GLU (Gated Linear Unit)
  • ApplicationContext 事件发布与监听机制详解
  • 反射机制的登录系统
  • PHP 8.0 升级到 PHP 8.1
  • 创建型模式
  • 基于 HT 的 3D 可视化智慧矿山开发实现
  • 从一开始的网络攻防(四):XSS
  • hadoop(服务器伪分布式搭建)
  • FastAdmin后台登录地址变更原理与手动修改方法-后台入口机制原理解析-优雅草卓伊凡
  • Hadoop安全机制深度剖析:Kerberos认证与HDFS ACL细粒度权限控制
  • 《Web安全之深度学习实战》读书笔记总结
  • AI赋能轮胎安全:基于YOLO11的智能裂纹检测系统
  • 基于springboot+vue+mysql的智慧社区设计与实现(源码+论文+开题报告)
  • Docker Swarm 集群使用记录
  • Matlab打开慢、加载慢的解决办法
  • 免费的一些工具收集
  • 【Oracle】centos7离线静默安装oracle11g(p13390677_112040)
  • Hive 向量化执行引擎 Vectorized Execution 常见 NPE 报错分析及解决
  • 全球天气预报5天(经纬度版)免费API接口教程
  • Python绘制数据(二)
  • JAVA面试宝典 -《微服务治理:从链路追踪到熔断》
  • 某邮生活旋转验证码识别
  • 算法竞赛备赛——【图论】求最短路径——小结
  • 前端之CSS
  • MyBatis之关联查询
  • WEB安全架构
  • Tomcat及Nginx部署使用
  • DevExpress WinForms v25.1 亮点:AI驱动的语义搜索、模板库更新