我需要一個列表,它是很多列表(枚舉列表)。現在列表正在使用彈出窗口(組合框),但正常的組合框並不是真的有幫助,因爲它裏面有太多的項目。當嘗試選擇遠離底部的項目時,會感到沮喪。打開時列表在屏幕上已滿。Unity搜索組合框
當開擴一個組合框,鍵入一個字母就跳到第一個字母,當我按下第二個字母列表將被跳轉到另一個第一個字母開始。例如,我想選擇DIAMOND - >我按D鍵,它會以D開頭進入列表。當我按I時,它將跳轉到以I開始而不是DI開始的項目。
是否有GUI的任何組件來搜索?
我需要一個列表,它是很多列表(枚舉列表)。現在列表正在使用彈出窗口(組合框),但正常的組合框並不是真的有幫助,因爲它裏面有太多的項目。當嘗試選擇遠離底部的項目時,會感到沮喪。打開時列表在屏幕上已滿。Unity搜索組合框
當開擴一個組合框,鍵入一個字母就跳到第一個字母,當我按下第二個字母列表將被跳轉到另一個第一個字母開始。例如,我想選擇DIAMOND - >我按D鍵,它會以D開頭進入列表。當我按I時,它將跳轉到以I開始而不是DI開始的項目。
是否有GUI的任何組件來搜索?
Unity沒有像你的搜索組件。
但你可以嘗試這樣的事情(SearchEnumLabel
功能):
using System;
using System.Globalization;
using System.Linq;
using UnityEditor;
public enum States
{
ABCDEF,
ACBDEF,
AdEXG,
bErDSa
}
[CustomEditor(typeof(ObjectControllerTester))]
[CanEditMultipleObjects]
public class ObjectControllerTesterEditor : Editor
{
States _selected;
public override void OnInspectorGUI()
{
_selected = SearchEnumLabel("My search enum", _selected);
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.LabelField("[Debug]Current selected: "+_selected);
}
private String _searchEnumText = "";
private bool _isSearchEnumLabelInSearch = false;
private T SearchEnumLabel<T>(String label, T state) where T : struct, IConvertible
{
if (!typeof(T).IsEnum)
{
EditorGUILayout.LabelField("T must be an enumerated type");
return state;
}
var states = Enum.GetValues(typeof (T)).Cast<object>().Select(o => o.ToString()).ToArray();
if (string.IsNullOrEmpty(_searchEnumText) && states.Length > 0) _searchEnumText = state.ToString(CultureInfo.InvariantCulture);
var text = EditorGUILayout.TextField(label, _searchEnumText);
if (text != _searchEnumText || _isSearchEnumLabelInSearch)
{
_searchEnumText = text;
var mach = states.Select((v,i)=>new {value = v, index = i}).FirstOrDefault(a => a.value.ToLower().StartsWith(text.ToLower()));
var targetState = state;
if (mach != null) targetState = (T) Enum.GetValues(typeof (T)).GetValue(mach.index);
EditorGUILayout.LabelField("Select closest: "+targetState);
Repaint();
state = targetState;
_isSearchEnumLabelInSearch = !string.Equals(_searchEnumText, targetState.ToString(CultureInfo.InvariantCulture), StringComparison.CurrentCultureIgnoreCase);
}
return state;
}
}
這個腳本會顯示這樣的事情:
默認視圖
輸入一些數據後
=== UPDATE ===快速選擇按鈕
using System;
using System.Globalization;
using System.Linq;
using UnityEditor;
using UnityEngine;
public enum States
{
ABCDEF,
ACBDEF,
AdEXG,
bErDSa,
sEOjsfl,
SdDiaso,
POsdjaow,
PSADJsd,
Oasdo,
IOQWEnds
}
[CustomEditor(typeof(ObjectControllerTester))]
[CanEditMultipleObjects]
public class ObjectControllerTesterEditor : Editor
{
States _selected;
public override void OnInspectorGUI()
{
_selected = SearchEnumLabel("My search enum", _selected);
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.LabelField("[Debug]Current selected: " + _selected);
}
private String _searchEnumText = "";
private bool _isSearchEnumLabelInSearch = false;
private T SearchEnumLabel<T>(String label, T state) where T : struct, IConvertible
{
if (!typeof(T).IsEnum)
{
EditorGUILayout.LabelField("T must be an enumerated type");
return state;
}
var states = Enum.GetValues(typeof(T)).Cast<object>().Select(o => o.ToString()).ToArray();
if (string.IsNullOrEmpty(_searchEnumText) && states.Length > 0) _searchEnumText = state.ToString(CultureInfo.InvariantCulture);
var text = EditorGUILayout.TextField(label, _searchEnumText);
if (text != _searchEnumText || _isSearchEnumLabelInSearch)
{
_searchEnumText = text;
var mach = states.Select((v, i) => new { value = v, index = i }).Where(a => a.value.ToLower().StartsWith(text.ToLower())).ToList();
var targetState = state;
if (mach.Any())
{
// many of results
targetState = (T)Enum.GetValues(typeof(T)).GetValue(mach[0].index);
EditorGUILayout.LabelField("Select closested: " + targetState);
Repaint();
var selected = GUILayout.SelectionGrid(-1, mach.Select(v => v.value).ToArray(), 4);
if (selected != -1)
{
targetState = (T)Enum.GetValues(typeof(T)).GetValue(mach[selected].index);
_searchEnumText = targetState.ToString(CultureInfo.InvariantCulture);
_isSearchEnumLabelInSearch = false;
GUI.FocusControl("FocusAway");
Repaint();
}
}
state = targetState;
_isSearchEnumLabelInSearch = !string.Equals(_searchEnumText, targetState.ToString(CultureInfo.InvariantCulture), StringComparison.CurrentCultureIgnoreCase);
}
return state;
}
}
點擊按鈕
這裏是我的解決方案,你可以隨意替換'EnumNBEvent'。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using Newborn.Pb.Event;
using System;
using System.Reflection;
using Google.Protobuf.Reflection;
using System.Text.RegularExpressions;
[CustomPropertyDrawer(typeof(EnumNBEvent), false)]
public class FSMEventDrawer : PropertyDrawer {
struct EnumStringValuePair : IComparable<EnumStringValuePair>
{
public string strValue;
public int intValue;
public int CompareTo(EnumStringValuePair another)
{
if (intValue < another.intValue)
return -1;
else if (intValue > another.intValue)
return 1;
return 0;
}
}
Dictionary<int, string> filters = new Dictionary<int, string>();
//string filter = string.Empty;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
int y = (int)position.position.y;
if (!filters.ContainsKey(y))
filters[y] = string.Empty;
EditorGUI.BeginProperty(position, label, property);
EditorGUI.LabelField(new Rect(position.x, position.y, 100, 20), property.name);
filters[y] = EditorGUI.TextField(new Rect(position.x + 100, position.y, 60, 15), filters[y]);
List<EnumStringValuePair> enumList = GetEnumList(filters[y]);
List<string> enumStrList = new List<string>(enumList.Count);
for (int i = 0; i < enumList.Count; ++i)
{
enumStrList.Add(enumList[i].strValue);
}
int selectedIndex = 0;
for (int i = 0; i < enumList.Count; ++i)
{
if (enumList[i].intValue == property.enumValueIndex)
{
selectedIndex = i;
break;
}
}
selectedIndex = EditorGUI.Popup(new Rect(position.x + 170, position.y, 200, 20), selectedIndex, enumStrList.ToArray());
if (enumList.Count > selectedIndex)
{
property.enumValueIndex = enumList[selectedIndex].intValue;
}
EditorGUI.EndProperty();
}
private List<EnumStringValuePair> GetEnumList(string filter)
{
List<EnumStringValuePair> allList = new List<EnumStringValuePair>();
Array enumValues = Enum.GetValues(typeof(EnumNBEvent));
for (int i = 0; i < enumValues.Length; ++i)
{
EnumStringValuePair pair = new EnumStringValuePair();
pair.strValue = enumValues.GetValue(i).ToString();
pair.intValue = (int)enumValues.GetValue(i);
allList.Add(pair);
}
List<EnumStringValuePair> ret = new List<EnumStringValuePair>();
Regex regex = new Regex(filter.ToLower());
for (int i = 0; i < allList.Count; ++i)
{
if (regex.IsMatch(allList[i].strValue.ToLower()))
{
ret.Add(allList[i]);
}
}
return ret;
}
}
哇,我也需要這個,謝謝 – Catwood
嗨@Randomyr,謝謝你的回答。我只是在打開一個新窗口時想到關於枚舉的列表。所以它就像一個按鈕旁邊的按鈕,我們可以點擊並打開窗口。所以所有枚舉列表都會在那裏,我們可以過濾並選擇我們想要的枚舉。那可能嗎? – Apin
@Apin,我已經更新了答案 - 你的意思是這種情況嗎? –