在写 EditorWindow 或者 Inspector 面板时,为了能清晰的表现某些功能或者状态、属性,常常需要用到一些 Unity 引擎中的图标,这时就需要一个能够显示和查找内置图标的功能。
首先看一下效果:


Unity 里其实内置了两套尺寸的图标,小图标共 2577 个,同时,由于 Unity 具有两种皮肤,浅色皮肤和深色 Pro 皮肤,因此为了保持更好的可读性,图标也对两种外观进行了适配,深色图标的名称一般是浅色图标的名称加 d_ 开头。
下面针对窗口的不同区域进行拆解。
首先拿到所有图标名称的列表,图标列表来自于 GitHub 上的一个用户的整理:
https://gist.github.com/MattRix/c1f7840ae2419d8eb2ec0695448d4321
然后需要排除一些非法图标(比如一些没有图片的图标):
private void OnEnable()
{
var all_icons = ico_list.Where(x => GetIcon(x) != null);
List<string> unique = new List<string>();
foreach (Texture2D x in Resources.FindObjectsOfTypeAll<Texture2D>())
{
GUIContent icoContent = GetIcon(x.name);
if (icoContent == null) continue;
if (!all_icons.Contains(x.name))
{
unique.Add(x.name);
}
}
ico_list = ico_list.ToList().Concat(unique).ToArray();
Resources.UnloadUnusedAssets();
System.GC.Collect();
}
GUIContent GetIcon(string icon_name)
{
GUIContent valid = null;
Debug.unityLogger.logEnabled = false;
if (!string.IsNullOrEmpty(icon_name)) valid = EditorGUIUtility.IconContent(icon_name);
Debug.unityLogger.logEnabled = true;
return valid?.image == null ? null : valid;
}
读取资源后做一次 GC。
准备一下窗口绘制需要用到的样式和数据:
static GUIContent iconSelected;
static List<GUIContent> iconContentListAll;
static List<GUIContent> iconContentListSmall;
static List<GUIContent> iconContentListBig;
static List<string> iconMissingNames;
static GUIStyle iconButtonStyle = null;
static GUIStyle iconPreviewBlack = null;
static GUIStyle iconPreviewWhite = null;
void InitIcons()
{
if (iconContentListSmall != null) return;
iconButtonStyle = new GUIStyle(EditorStyles.miniButton);
iconButtonStyle.margin = new RectOffset(0, 0, 0, 0);
iconButtonStyle.fixedHeight = 0;
iconPreviewBlack = new GUIStyle(iconButtonStyle);
AllTheTEXTURES(ref iconPreviewBlack, Texture2DPixel(new Color(0.15f, 0.15f, 0.15f)));
iconPreviewWhite = new GUIStyle(iconButtonStyle);
AllTheTEXTURES(ref iconPreviewWhite, Texture2DPixel(new Color(0.85f, 0.85f, 0.85f)));
iconMissingNames = new List<string>();
iconContentListSmall = new List<GUIContent>();
iconContentListBig = new List<GUIContent>();
iconContentListAll = new List<GUIContent>();
for (var i = 0; i < ico_list.Length; ++i)
{
GUIContent ico = GetIcon(ico_list[i]);
if (ico == null)
{
iconMissingNames.Add(ico_list[i]);
continue;
}
ico.tooltip = ico_list[i];
iconContentListAll.Add(ico);
if (!(ico.image.width <= 36 || ico.image.height <= 36))
iconContentListBig.Add(ico);
else iconContentListSmall.Add(ico);
}
}
void AllTheTEXTURES(ref GUIStyle s, Texture2D t)
{
s.hover.background = s.onHover.background = s.focused.background = s.onFocused.background = s.active.background = s.onActive.background = s.normal.background = s.onNormal.background = t;
s.hover.scaledBackgrounds = s.onHover.scaledBackgrounds = s.focused.scaledBackgrounds = s.onFocused.scaledBackgrounds = s.active.scaledBackgrounds = s.onActive.scaledBackgrounds = s.normal.scaledBackgrounds = s.onNormal.scaledBackgrounds = new Texture2D[] { t };
}