2016-04-27 6 views
0

リストがたくさんあるリストが必要です(列挙リスト)。そして現在、リストはポップアップ(コンボボックス)を使用していますが、通常のコンボボックスは、その内部のアイテムが多すぎるため、実際には役に立ちません。遠く離れているアイテムを選択しようとすると、なんとなくイライラします。このリストは、開いたときに画面にいっぱいです。Unity GUIのコンボボックスの検索

List Picture

コンボボックスをopenningし、文字を入力し、それは、私は2番目の文字を押すと、リストが別の最初の文字の先頭にジャンプすることになる、最初の文字だけをジャンプします。例えば、DIAMOND - > Dを押すとDスタートでリストに移動します。私がIを押すと、DIの代わりにIで始まる項目にジャンプします。

検索の対象となるGUIのコンポーネントはありますか?

答えて

4

ユニティはあなたのような検索のためのコンポーネントを持っていません。

しかし、あなたはこのような何か(SearchEnumLabel機能)を試すことができます。

Default vision

入力いくつかのデータの後

デフォルトビュー:

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; 
    } 
} 

は、このスクリプトは次のようなものが表示されます

After input some data

=== 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; 
    } 
} 

タップボタンで

より複雑な変種がターゲット列挙ここ Tap to button to select target enum

+0

うわー、私もこれが必要です、ありがとう – Catwood

+0

こんにちは@Randomyr、あなたの答えをありがとう。私はちょうど新しいウィンドウで列挙型のリストについて開いて考えている。だから、オブジェクトフィールドの隣にあるボタンのように、私たちはクリックしてウィンドウを開くことができます。したがって、すべての列挙型リストがそこにあり、私たちは必要な列挙型をフィルタリングして選択できます。それは可能ですか? – Apin

+0

@Apin、私は答えを更新しました - あなたはこの場合ですか? –

0

私の解決策がある選択し、あなたは好きなように '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; 
} 

} 
関連する問題