首先,它完成后大概是这个样子的:
模糊查找
using System;
using UnityEngine;
using UnityEditor;
using System.Reflection;
using System.Collections.Generic;
using System.Text.RegularExpressions;
public class FilterTestWindow : EditorWindow
{
private const string mDefaultKey = "Filter_Test";
private static List mDefaultTypeList;
private static List mSelectedTypeList;
string mSearchPath = ""; //检索字段
Vector2 scrollPos; //滚动条位置
bool isShowOnlyEnabled = false; //仅显示选中的类
[MenuItem("Window/Filter Test Settings")]
static void Init()
{
if (mSelectedTypeList == null)
LoadDefaults();
FilterTestWindow window = (FilterTestWindow)EditorWindow.GetWindow(typeof(FilterTestWindow), true, "Filter Test");
window.minSize = new Vector2(325, 300); //限制最小尺寸
//window.maxSize = new Vector2(325, 800); //限制最大尺寸
}
//通过EditorPrefs的key 收集选中类型信息
static void LoadDefaults()
{
mSelectedTypeList = new List();
string rawDefaults = EditorPrefs.GetString(mDefaultKey);
string[] classParts = rawDefaults.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
foreach (string classPart in classParts)
{
mSelectedTypeList.Add(classPart.Trim());
}
}
public void OnEnable()
{
if (mDefaultTypeList == null)
{
mDefaultTypeList = new List();
Assembly asm = typeof(Component).Assembly;
Dictionary tempTypeList = new Dictionary();
string tempTypeName;
string tempNamespace;
string[] words;
//加入选中类型 分离命名空间和类名
foreach (string defaultTypeName in mSelectedTypeList)
{
words = defaultTypeName.Split('.');
if (words.Length == 1)
{
tempNamespace = "";
tempTypeName = defaultTypeName;
}
else
{
tempNamespace = words[0];
tempTypeName = words[1];
}
mDefaultTypeList.Add(new FilterTestObject(tempNamespace, tempTypeName, true));
tempTypeList.Add(tempTypeName, true);
}
//加入UnityEngine默认类型
foreach (Type type in asm.GetTypes())
{
if (typeof(Component).IsAssignableFrom(type))
{
if (type != typeof(Component) && type != typeof(Behaviour) && type != typeof(MonoBehaviour))
{
if (!tempTypeList.ContainsKey(type.Name))
{
mDefaultTypeList.Add(new FilterTestObject("UnityEngine", type.Name, false));
tempTypeList.Add(type.Name, false);
}
}
}
}
//加入所有自定义类型
Assembly[] currDomainAssemblies = AppDomain.CurrentDomain.GetAssemblies();
string asmPath;
foreach (Assembly currDomainAsm in currDomainAssemblies)
{
asmPath = currDomainAsm.CodeBase;
if (asmPath.EndsWith("Assembly-UnityScript.dll") || asmPath.EndsWith("Assembly-CSharp.dll"))
{
foreach (System.Type type in currDomainAsm.GetTypes())
{
if (typeof(MonoBehaviour).IsAssignableFrom(type))
{
if (!tempTypeList.ContainsKey(type.Name))
{
mDefaultTypeList.Add(new FilterTestObject("", type.Name, false));
tempTypeList.Add(type.Name, false);
}
}
}
}
}
//按字母顺序排列
SortList();
}
}
private static void SortList()
{
FilterTestComparer comparer = new FilterTestComparer();
mDefaultTypeList.Sort(comparer);
}
//绘制窗口
public void OnGUI()
{
GUILayout.Label("Filter Test Window", EditorStyles.boldLabel);
EditorGUILayout.Space();
mSearchPath = EditorGUILayout.TextField(new GUIContent("Filter"), mSearchPath, GUILayout.Width(300.0f));
EditorGUILayout.Space();
//开始滚动条布局
scrollPos = EditorGUILayout.BeginScrollView(scrollPos, false, false, GUILayout.Width(300), GUILayout.Height(position.height - 140));
int listCount = 0;
//加入简易正则筛选测试
bool bRegexMode = false;
Regex regex = null;
string regexStr = "";
if (mSearchPath.StartsWith("*"))
{
bRegexMode = true;
regexStr = "\\w" + mSearchPath.Substring(1, mSearchPath.Length - 1).ToLower();
regex = new Regex(regexStr);
}
foreach (FilterTestObject testObj in mDefaultTypeList)
{
//正则测试条件
if (mSearchPath == "" || bRegexMode && regex.Match(testObj.TypeName.ToLower()).Success|| testObj.TypeName.ToLower().StartsWith(mSearchPath.ToLower()))
//if (mSearchPath == "" || autoPersistObj.TypeName.ToLower().StartsWith(mSearchPath.ToLower()))
{
if (!isShowOnlyEnabled || testObj.IsSelected)
{
GUILayout.BeginHorizontal(GUILayout.Width(250));
GUILayout.Label(testObj.TypeName, GUILayout.Width(200));
if (!testObj.IsSelected)
{
if (GUILayout.Button("Add"))
{
AddDefault(testObj.GetFullClassName());
testObj.IsSelected = true;
if (EditorApplication.isPlaying || EditorApplication.isPaused)
{
//Do Something...For Extension
}
}
}
else
{
if (GUILayout.Button("Remove"))
{
RemoveDefault(testObj.GetFullClassName());
testObj.IsSelected = false;
if (EditorApplication.isPlaying || EditorApplication.isPaused)
{
//Do Something...For Extension
}
}
}
GUILayout.EndHorizontal();
listCount++;
}
}
}
//筛选提示
if (listCount == 0)
{
if (isShowOnlyEnabled && mSearchPath == "")
{
GUILayout.Label("No Components Are Selected");
}
else
{
GUILayout.Label("Please Broaden Your Search");
}
}
EditorGUILayout.EndScrollView();
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
GUILayout.Label("Show Only Enabled"); //仅显示选中类
isShowOnlyEnabled = EditorGUILayout.Toggle(isShowOnlyEnabled, GUILayout.ExpandWidth(true));
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
if (mSelectedTypeList.Count > 0)
{
EditorGUILayout.Space();
if (GUILayout.Button("Remove All"))//移除所有选中
{
foreach (FilterTestObject obj in mDefaultTypeList)
{
if (obj.IsSelected)
{
RemoveDefault(obj.GetFullClassName());
obj.IsSelected = false;
}
}
}
}
EditorGUILayout.Space();
if (GUILayout.Button("Print")) //简易拓展功能 打印所有选中类型
{
foreach (FilterTestObject obj in mDefaultTypeList)
{
if (obj.IsSelected)
{
Debug.Log(obj.GetFullClassName());
}
}
}
EditorGUILayout.Space();
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
}
public static void AddDefault(string className)
{
if (!mSelectedTypeList.Contains(className))
{
mSelectedTypeList.Add(className);
SaveDefaults();
}
}
public static void RemoveDefault(string className)
{
if (mSelectedTypeList.Contains(className))
{
mSelectedTypeList.Remove(className);
SaveDefaults();
}
}
//保存信息到EditorPrefs
private static void SaveDefaults()
{
string defaultStr = string.Join("|", mSelectedTypeList.ToArray());
EditorPrefs.SetString(mDefaultKey, defaultStr);
}
}
public class FilterTestObject
{
private string typeName;
private string namespaceStr;
private bool isSelected;
public bool IsSelected
{
get { return isSelected; }
set { isSelected = value; }
}
public FilterTestObject(string namespaceStr, string typeName, bool bSelected)
{
this.typeName = typeName;
this.namespaceStr = namespaceStr;
this.isSelected = bSelected;
}
public string TypeName
{
get { return typeName; }
}
public string GetFullClassName()
{
if (namespaceStr.Length > 0) return namespaceStr + "." + typeName;
else return typeName;
}
}
public class FilterTestComparer : IComparer
{
public int Compare(FilterTestObject x, FilterTestObject y)
{
if (x == null) return (y == null ? 0 : -1);
if (y == null) return 1;
return x.TypeName.CompareTo(y.TypeName);
}
}
已更新:
Unity3D 如何在退出运行模式后保存修改数据