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

给你的Unity编辑器添加实现类似 Odin 的 条件显示字段 (ShowIf/HideIf) 功能

自己常用的一个预制功能模块,用到这个开关显示的功能,但又不想依赖Odin。
一个是自己穷,用不起Odin,二是如果我的包给别人用,依赖的太多而且还是收费的,会不会被人炸掉祖坟。

一、效果演示

请添加图片描述
在脚本的观察面板上,通过一些变量开关,显示和隐藏某些字段。

目前Unity没有这个Attribute,所以要么你用诸如Odin,要么自己用AI搓一个

二、需求来源

自己常用的一个预制功能模块,用到这个开关显示的功能,但又不想依赖Odin。
一个是自己穷,用不起Odin,二是如果我的包给别人用,依赖的太多而且还是收费的,会不会被人炸掉祖坟。
请添加图片描述

三、功能脚本组成

脚本1,Editor下:ConditionalFieldDrawer.cs,注意,必须放在Editor下
脚本2,Runtime下:ConditionalFieldAttribute.cs,不能放在Editor下
脚本3,测试脚本:Demo.cs
在这里插入图片描述
挂载后到物体并测试:
在这里插入图片描述

四、源码

1、ConditionalFieldDrawer.cs 清单

using UnityEditor;
using UnityEngine;[CustomPropertyDrawer(typeof(ConditionalFieldAttribute))]
public class ConditionalFieldDrawer : PropertyDrawer
{public override void OnGUI(Rect position, SerializedProperty property, GUIContent label){ConditionalFieldAttribute condHAtt = (ConditionalFieldAttribute)attribute;// 找到比较的字段SerializedProperty comparedField = property.serializedObject.FindProperty(condHAtt.ComparedPropertyName);if (comparedField != null && comparedField.propertyType == SerializedPropertyType.Boolean){bool enabled = comparedField.boolValue == condHAtt.ExpectedValue;if (enabled){EditorGUI.PropertyField(position, property, label, true);}}else{// 如果字段没找到,正常显示EditorGUI.PropertyField(position, property, label, true);}}public override float GetPropertyHeight(SerializedProperty property, GUIContent label){ConditionalFieldAttribute condHAtt = (ConditionalFieldAttribute)attribute;SerializedProperty comparedField = property.serializedObject.FindProperty(condHAtt.ComparedPropertyName);if (comparedField != null && comparedField.propertyType == SerializedPropertyType.Boolean){bool enabled = comparedField.boolValue == condHAtt.ExpectedValue;return enabled ? EditorGUI.GetPropertyHeight(property, label, true) : 0;}return EditorGUI.GetPropertyHeight(property, label, true);}
}

2、ConditionalFieldAttribute.cs 清单

using System;
using UnityEngine;[AttributeUsage(AttributeTargets.Field, AllowMultiple = true, Inherited = true)]
public class ConditionalFieldAttribute : PropertyAttribute
{public string ComparedPropertyName { get; private set; }public bool ExpectedValue { get; private set; }public ConditionalFieldAttribute(string comparedPropertyName, bool expectedValue = true){this.ComparedPropertyName = comparedPropertyName;this.ExpectedValue = expectedValue;}
}

3、Demo.cs 清单

using UnityEngine;public class ConditionalFieldTest : MonoBehaviour
{[Header("总开关")]public bool masterSwitch;[Header("子选项,只在 masterSwitch == true 时显示")][ConditionalField(nameof(masterSwitch), true)]public bool optionA;[ConditionalField(nameof(masterSwitch), true)]public bool optionB;[Header("反向测试:只有当 masterSwitch == false 时才显示")][ConditionalField(nameof(masterSwitch), false)]public string hiddenMessage = "当 masterSwitch == false 时才看得见";[Header("多层嵌套测试")]public bool subSwitch;[ConditionalField(nameof(subSwitch), true)]public int subValue;
}

五、致谢:

感谢GPT,从前的搜索时代是信息平权,现在的GPT时代是知识平权。
网友说:三天不学习,赶不上GPT。

http://www.dtcms.com/a/340301.html

相关文章:

  • Scikit-learn 预处理函数分类详解
  • pnpm : 无法加载文件 C:\Program Files\nodejs\pnpm.ps1,因为在此系统上禁止运行脚本。
  • 在 React 中,​父子组件之间的通信(传参和传方法)
  • scikit-learn/sklearn学习|变量去中心化和标准化
  • 2.3 Flink的核心概念解析
  • 详解flink java table api基础(三)
  • Flink Stream API - 顶层Operator接口StreamOperator源码超详细讲解
  • OSPF 典型组网
  • CISP-PTE之路--10文
  • 公有地址和私有地址
  • 【GPT入门】第51课 将hf模型转换为GGUF
  • 深入(流批【牛批】框架)Flink的机制
  • 【Java后端】Spring Boot 全局异常处理最佳实践
  • ssl代理
  • 一会儿能ping通一会ping不通解决方案
  • JavaScript手录18-ajax:异步请求与项目上线部署
  • AI 自动化编程 trae 体验 页面添加富编辑器
  • (5)软件包管理器 yum | Vim 编辑器 | Vim 文本批量化操作 | 配置 Vim
  • 深度解析:RESTful API中的404错误 - 不是所有404都是Bug
  • Vue 3项目中的路由管理和状态管理系统
  • 【Day 31】Linux-LNMP
  • MySQL基础操作
  • SpringBoot + MyBatis-Plus 使用 listObjs 报 ClassCastException 的原因与解决办法
  • Rabbit 实战指南-学习笔记
  • HTML+CSS:浮动详解
  • 3D文档控件Aspose.3D实用教程:使用 C# 构建 OBJ 到 U3D 转换器
  • awk 基础用法示例
  • 测试DuckDB插件对不同格式xlsx文件的读写效率
  • MyCAT分库分表
  • Go特有的安全漏洞及渗透测试利用方法(通俗易懂)