Unity C#:如何实现枚举类型的Inspector下拉选择列表?
首先得给你指出来:你原来的写法有个核心问题——C#的枚举类型根本不支持字符串作为成员的值,默认所有枚举成员都是整型(int),所以AssemblyType{ Name = "NameOfFile.dll" }这种写法连编译都通不过,更别说在Inspector里显示了。
不过别担心,我们可以用变通的方法实现你想要的效果:让枚举项关联对应的dll文件名,同时在Inspector里显示一个可选择枚举值的下拉列表(类似你说的"Day Colours"效果)。下面分步骤给你讲:
1. 正确定义枚举并关联文件名
我们可以用自定义特性来给每个枚举项绑定对应的dll文件名,这是最规范灵活的做法:
// 自定义特性,用来存储枚举项对应的dll文件名 public class AssemblyFileNameAttribute : System.Attribute { public string FileName { get; } public AssemblyFileNameAttribute(string fileName) { FileName = fileName; } } // 修正后的枚举定义 public enum AssemblyType { [AssemblyFileName("NameOfFile.dll")] Name, [AssemblyFileName("AnotherAssembly.dll")] AnotherAssembly, [AssemblyFileName("ThirdPartyLib.dll")] ThirdPartyLib }
如果觉得自定义特性麻烦,临时用Tooltip也能凑合用(只是读取的时候要处理Tooltip文本),但自定义特性的扩展性更好。
2. 写扩展方法快速获取文件名
接下来写一个扩展方法,让你能从枚举值直接拿到对应的dll文件名,不用每次写一堆if/switch:
public static class AssemblyTypeExtensions { public static string GetDllFileName(this AssemblyType assemblyType) { // 获取枚举项对应的FieldInfo var fieldInfo = assemblyType.GetType().GetField(assemblyType.ToString()); // 读取自定义特性 var fileNameAttr = fieldInfo.GetCustomAttribute<AssemblyFileNameAttribute>(); // 如果有特性就返回文件名,没有就返回枚举项的名字作为 fallback return fileNameAttr?.FileName ?? assemblyType.ToString(); } }
这样在代码里使用的时候就非常方便:
// 比如从列表里拿第一个项的文件名 string firstDll = requiredAssemblies[0].GetDllFileName();
3. 让Inspector显示友好的可重排下拉列表
默认情况下,public List<AssemblyType> requiredAssemblies = new List<AssemblyType>();在Inspector里已经会显示一个可编辑的列表,每个项是枚举下拉框,但如果你想要更美观的效果(比如像"Day Colours"那种带标题、可拖拽重排的列表),可以写一个简单的Editor脚本定制显示:
using UnityEditor; using UnityEngine; // 替换成你的脚本类名 [CustomEditor(typeof(YourManagerScript))] public class AssemblyListEditor : Editor { private ReorderableList _assemblyReorderableList; private void OnEnable() { // 找到脚本里的requiredAssemblies字段 var listProperty = serializedObject.FindProperty("requiredAssemblies"); // 创建可重排列表 _assemblyReorderableList = new ReorderableList(serializedObject, listProperty, true, true, true, true) { // 绘制列表头部 drawHeaderCallback = rect => EditorGUI.LabelField(rect, "Required Assemblies (DLLs)"), // 绘制每个列表项 drawElementCallback = (rect, index, isActive, isFocused) => { var elementProperty = listProperty.GetArrayElementAtIndex(index); rect.y += 2; // 稍微调整垂直间距,避免贴太紧 EditorGUI.PropertyField( new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), elementProperty, new GUIContent($"Assembly {index + 1}") ); } }; } public override void OnInspectorGUI() { serializedObject.Update(); // 绘制自定义列表 _assemblyReorderableList.DoLayoutList(); serializedObject.ApplyModifiedProperties(); } }
把上面的YourManagerScript替换成你实际挂载requiredAssemblies列表的脚本类名,这样在Inspector里就能看到一个整洁的可重排列表,每个项都是AssemblyType的下拉选择框,完全符合你的需求。
补充:简单场景的替代方案
如果你的枚举项很少,也可以直接用switch语句映射文件名,不用自定义特性,简单直接:
public static string GetFileName(AssemblyType type) { return type switch { AssemblyType.Name => "NameOfFile.dll", AssemblyType.AnotherAssembly => "AnotherAssembly.dll", _ => type.ToString() }; }
内容的提问来源于stack exchange,提问作者FlamingGenius

