Unity中实现嵌套枚举层级联动下拉菜单的技术问询
问题描述
我在Unity开发游戏时,想要用嵌套枚举结构,让对应的层级下拉菜单在Inspector面板里动态显示。目前已经写了如下代码:
public class ItemEnums{ public enum Type { CraftingMaterial, Equipment, Food, Miscellaneous } public enum FoodType { Potion, Edible, Drink } public enum EdibleType { Meat, Herbs, Fruit, Vegetables, ProcessedFood } } [CreateAssetMenu(fileName = "New Item", menuName = "Create new Item")] [System.Serializable] public class Items : ScriptableObject { public int id; public string itemName; [TextArea(3, 3)] public string description; public GameObject prefab; public Texture icon; public int maxStack; public float weight; public int baseValue; public ItemEnums.Type type; }
现在需要实现:当选择Type为Food时,显示FoodType的下拉菜单;当FoodType选择Edible时,再显示EdibleType的下拉菜单,该怎么实现?
解决方案
1. 扩展Items类,添加所需枚举字段
先在Items类里补上FoodType和EdibleType的公共字段,后面我们用编辑器脚本控制它们的显示/隐藏:
[CreateAssetMenu(fileName = "New Item", menuName = "Create new Item")] [System.Serializable] public class Items : ScriptableObject { public int id; public string itemName; [TextArea(3, 3)] public string description; public GameObject prefab; public Texture icon; public int maxStack; public float weight; public int baseValue; public ItemEnums.Type type; // 新增以下两个枚举字段 public ItemEnums.FoodType foodType; public ItemEnums.EdibleType edibleType; }
2. 编写自定义Editor脚本
Unity默认的Inspector面板不支持这种动态显示逻辑,得写个自定义Editor脚本来控制字段的显示状态。在项目里新建一个**必须叫Editor**的文件夹(Unity只会识别这个名字下的编辑器脚本),然后创建ItemsEditor.cs脚本:
using UnityEditor; using UnityEngine; [CustomEditor(typeof(Items))] public class ItemsEditor : Editor { public override void OnInspectorGUI() { Items item = (Items)target; // 先绘制除了三个枚举之外的所有默认字段 DrawPropertiesExcluding(serializedObject, "type", "foodType", "edibleType"); // 绘制Type枚举下拉 serializedObject.Update(); SerializedProperty typeProp = serializedObject.FindProperty("type"); EditorGUILayout.PropertyField(typeProp); serializedObject.ApplyModifiedProperties(); // 当Type选Food时,显示FoodType下拉 if (item.type == ItemEnums.Type.Food) { serializedObject.Update(); SerializedProperty foodTypeProp = serializedObject.FindProperty("foodType"); EditorGUILayout.PropertyField(foodTypeProp); serializedObject.ApplyModifiedProperties(); // 当FoodType选Edible时,显示EdibleType下拉 if (item.foodType == ItemEnums.FoodType.Edible) { serializedObject.Update(); SerializedProperty edibleTypeProp = serializedObject.FindProperty("edibleType"); EditorGUILayout.PropertyField(edibleTypeProp); serializedObject.ApplyModifiedProperties(); } } // 保存Inspector里的修改 if (GUI.changed) { EditorUtility.SetDirty(item); } } }
注意事项
- 编辑器脚本必须放在
Editor文件夹下,不然会被打包进游戏包引发错误。 - 用
SerializedProperty访问字段能保证Undo/Redo功能正常工作,比直接操作对象字段更稳妥。 - 切换枚举选项时,Inspector会自动刷新,动态显示/隐藏对应下拉菜单。
内容的提问来源于stack exchange,提问作者Jamelaumn
相关产品推荐
相关产品推荐

