様々なEditorWindow② - SearchableWIndow
様々なEditorWindow①の続きです
SearchableWIndow
このWindowは機能的にはEditorWindowと同じですが、アセットの検索機能を(privateなmethodとして)持ったWindowです。現段階ではReflectionを使わない限り使い道はありません。 どうしても使ってみたい、という方は
「SearchFilter」
「SearchableEditorWindow.CreateSearchFilter」
「SearchableEditorWindow.m_SearchMode」
「HierarchyProperty」
「HierarchyProperty.SetSearchFilter」
「FilteredHierarchy」
「FilteredHierarchy.SearchAllAssets」
「FilteredHierarchy.m_Results」
を逆コンパイルして調べてみると幸せになれるかも。
こんな感じでUnityの検索機能を自由に使うことができる
俺が実際にプロジェクトでSearchableWindowを使ってる所のソースコード
そのままじゃ動かないので参考程度に。
using UnityEngine; using UnityEditor; using System.Linq; using System.Collections; using System.Reflection; using System; using System.Collections.Generic; namespace CommandPallet.Plugins { public class SearchAssets : PluginBase { static Type type = typeof(SearchableEditorWindow); static List<FilterResult> results = new List<FilterResult> (); static Dictionary<int,AssetData> assets = new Dictionary<int,AssetData> (); private string text; public override void PalletOnGUI () { //SearchFieldGUIを呼び出すだけでSearchFieldが使えたりもする //typeof(SearchableEditorWindow).GetMethod ("SearchFieldGUI", (BindingFlags.Instance | BindingFlags.NonPublic)).Invoke (window, new object[0]); text = EditorGUILayout.TextField (text); object hierarchyProperty = CreateInstance ("UnityEditor.HierarchyProperty", new object{HierarchyType.Assets}); object filteredHierarchy = CreateInstance ("UnityEditor.FilteredHierarchy", new object{HierarchyType.Assets}); GetMethod (hierarchyProperty, "SetSearchFilter", new Type{ typeof(SearchFilter)}).Invoke (hierarchyProperty, new object{CreateFilter ()}); GetMethod (filteredHierarchy, "SearchAllAssets", new Type{hierarchyProperty.GetType ()}).Invoke (filteredHierarchy, new object{hierarchyProperty}); results.Clear (); foreach (object o in GetNonPublicField<object> ("m_Results", filteredHierarchy)) { results.Add (new FilterResult { instanceID=GetPublicField<int> ("instanceID", o), name=GetPublicField<string> ("name", o), hasChildren= GetPublicField<bool> ("hasChildren", o), colorCode=GetPublicField<int> ("colorCode", o), isMainRepresentation= GetPublicField<bool> ("isMainRepresentation", o), hasFullPreviewImage=GetPublicField<bool> ("hasFullPreviewImage", o), isFolder= GetPublicField<bool> ("isFolder", o), type=GetPublicField<HierarchyType> ("type", o), guid=GetPublicField<string> ("guid", o), icon=GetPublicField<Texture> ("icon", o)}); } results.ForEach (result => { AssetData asset = null; if (assets.ContainsKey (result.instanceID)) { asset = assets [result.instanceID]; } else { asset = new AssetData{ instanceID=result.instanceID, assetName=result.name, assetPath=AssetDatabase.GetAssetPath (result.instanceID), assetIcon=AssetDatabase.GetCachedIcon (AssetDatabase.GetAssetPath (result.instanceID))}; } Draw (asset); }); } private void Draw (AssetData asset) { GUILayout.BeginHorizontal (); GUILayout.Label (asset.assetIcon); GUILayout.BeginVertical (); GUILayout.Label (asset.assetName); GUILayout.Label (asset.assetPath); GUILayout.EndVertical (); GUILayout.EndHorizontal (); EditorGUI.BeginDisabledGroup (false); GUILayout.Label ("-----------------------"); EditorGUI.EndDisabledGroup (); } private MethodInfo GetMethod (object instance, string methodName, Type types) { return instance.GetType ().GetMethod (methodName, (BindingFlags.Instance | BindingFlags.NonPublic), null, types, null); } private object CreateInstance (string typeName, object parameters) { return Assembly.Load ("UnityEditor.dll").CreateInstance (typeName, false, BindingFlags.Default | BindingFlags.CreateInstance, null, parameters, null, null); } private SearchFilter CreateFilter () { return (SearchFilter)type.GetMethod ("CreateFilter", (BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance), null, new Type{typeof(string),typeof(SearchableEditorWindow.SearchMode)}, null).Invoke (palletWindow, new object[]{text,GetNonPublicField<SearchableEditorWindow.SearchMode> ("m_SearchMode", palletWindow)}); } private T GetPublicField<T> (string fieldName, object obj) { FieldInfo finfo = obj.GetType ().GetField (fieldName, (BindingFlags.Public | BindingFlags.Instance)); return finfo != null ? (T)finfo.GetValue (obj) : default(T); } private T GetNonPublicField<T> (string fieldName, object obj) { return (T)obj.GetType ().GetField (fieldName, (BindingFlags.NonPublic | BindingFlags.Instance)).GetValue (obj); } } }