Unity3D脚本组件中如何实现带变量显隐的下拉菜单?
Unity3D 实现下拉菜单切换显示对应变量的方案
核心思路
通过自定义编辑器脚本结合Unity序列化系统,根据下拉菜单(枚举)的选中值,动态显示/隐藏对应可编辑变量,完全复刻RigidBody2D的Body Type交互逻辑。
步骤1:编写业务逻辑脚本
先定义包含枚举和对应变量的MonoBehaviour脚本,用[HideInInspector]默认隐藏所有类型专属变量,交给编辑器脚本控制显示:
using UnityEngine; public class CustomBody : MonoBehaviour { // 定义下拉菜单的选项枚举 public enum BodyType { Dynamic, Kinematic, Static } // 下拉菜单选中值 public BodyType currentBodyType; // Dynamic类型专属变量 [HideInInspector] public float mass; [HideInInspector] public bool useGravity; // Kinematic类型专属变量 [HideInInspector] public float maxSpeed; [HideInInspector] public bool enableMovement; // Static类型可根据需求添加变量 }
步骤2:编写自定义编辑器脚本
创建编辑器脚本(必须放在Editor文件夹下),重写Inspector的绘制逻辑,根据枚举值动态渲染对应字段:
using UnityEditor; using UnityEngine; // 指定该编辑器脚本对应处理的业务脚本 [CustomEditor(typeof(CustomBody))] public class CustomBodyEditor : Editor { // 序列化属性,用于和Unity编辑器序列化系统交互 private SerializedProperty _bodyTypeProp; private SerializedProperty _massProp; private SerializedProperty _useGravityProp; private SerializedProperty _maxSpeedProp; private SerializedProperty _enableMovementProp; private void OnEnable() { // 从序列化对象中获取对应属性 _bodyTypeProp = serializedObject.FindProperty("currentBodyType"); _massProp = serializedObject.FindProperty("mass"); _useGravityProp = serializedObject.FindProperty("useGravity"); _maxSpeedProp = serializedObject.FindProperty("maxSpeed"); _enableMovementProp = serializedObject.FindProperty("enableMovement"); } public override void OnInspectorGUI() { // 更新序列化对象的状态 serializedObject.Update(); // 绘制下拉菜单(自动识别枚举类型) EditorGUILayout.PropertyField(_bodyTypeProp); // 根据选中的枚举值,显示对应变量 var selectedType = (CustomBody.BodyType)_bodyTypeProp.enumValueIndex; switch (selectedType) { case CustomBody.BodyType.Dynamic: EditorGUILayout.PropertyField(_massProp); EditorGUILayout.PropertyField(_useGravityProp); break; case CustomBody.BodyType.Kinematic: EditorGUILayout.PropertyField(_maxSpeedProp); EditorGUILayout.PropertyField(_enableMovementProp); break; case CustomBody.BodyType.Static: EditorGUILayout.HelpBox("静态物体无额外可配置变量", MessageType.Info); break; } // 应用对序列化对象的修改 serializedObject.ApplyModifiedProperties(); } }
关键注意事项
- 编辑器脚本必须放在
Editor目录下,否则Unity不会将其识别为编辑器扩展代码 - 使用
SerializedProperty而非直接访问脚本变量,是为了兼容Unity的序列化机制,避免出现数据不同步、多对象编辑失效等问题 - 若需要更复杂的布局(比如折叠组、分隔线),可以结合
EditorGUILayout.Space()、EditorGUILayout.Foldout()等方法扩展 - 该方案支持多对象批量编辑,选中多个挂载了
CustomBody脚本的物体时,编辑器会自动处理同步逻辑
内容的提问来源于stack exchange,提问作者O Majestático
相关产品推荐
相关产品推荐

