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

给你的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.xdnf.cn/news/18306.html

相关文章:

  • word——如何给封面、目录、摘要、正文设置不同的页码
  • 路由器NAT的类型测定
  • vue:vue中的ref和reactive
  • 【LLMs篇】18:基于EasyR1的Qwen2.5-VL GRPO训练
  • 层在init中只为创建线性层,forward的对线性层中间加非线性运算。且分层定义是为了把原本一长个代码的初始化和运算放到一个组合中。
  • 机械革命电竞控制台一直加载无法点击故障
  • MySQL事务及原理详解
  • 牛津大学xDeepMind 自然语言处理(3)
  • 工业电脑选得好生产效率节节高稳定可靠之选
  • C/C++ 与嵌入式岗位常见笔试题详解
  • Mac电脑上虚拟机共享文件夹权限问题
  • vscode连接docker
  • WIFI国家码修改信道方法_高通平台
  • 精品方案 | GCKontrol与OMNeT++联合仿真在机载网络性能分析中的应用
  • mvdr波束形成
  • Linux系统之部署nullboard任务管理工具
  • ios八股文 -- Objective-c
  • iOS 应用上架常见问题与解决方案,多工具组合的实战经验
  • Node.js中的Prisma应用:现代数据库开发的最佳实践
  • 单片机通信协议核心关系梳理笔记(UART/USART/232/485/SPI/12C/LIN/BLE/WIFI)
  • leetcode7二分查找_69 and 34
  • 链表的核心:“增删改查”
  • Nginx 负载均衡和缓存配置
  • 【软考架构】净室软件工程
  • Gin自定义Error中间件
  • SQL-leetcode— 2356. 每位教师所教授的科目种类的数量
  • 手机 浏览器调用摄像头扫描二维码Quagga
  • 2026 济南淀粉深加工展览会亮点:玉米科技与未来产业发展
  • 03-dockerfile
  • C++继承中的虚函数机制:从单继承到多继承的深度解析