Unity 内置图标

作Unity工具的时候,功能虽然很重要,但是美观也很重要。所以,用Unity内置自带的图标,会感觉更好看一点。

那么问题来了,你怎么得到Unity的内置图标呢?

雨松MOMO写过个博客,他反编译了一下editor的dll,用正则把图标信息给提取了出来。可是没看过反编译怎么办?【雨松MOMO:他的图标

那其实也还有其他的方法。我们可以直接用 Resources 的 FindObjectsOfTypeAll 先看看。

/*
 * 查看所有 Textures
 * 
 * 
 * 
 */


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class UnityIconsWindow : EditorWindow
{
    
    

    [MenuItem(("JJJ/Unity Textures Window"))]
    static void Init()
    {
    
    
        UnityIconsWindow window = EditorWindow.GetWindow<UnityIconsWindow>("Unity Textures Window");
        //加载所有Texture2D
        window.textures = Resources.FindObjectsOfTypeAll<Texture2D>();
        window.minSize = new Vector2(200, 400);

        //用于GUI
        window.fullRect = new Rect();
        foreach (var texture in window.textures)
        {
    
    
            window.fullRect.height += texture.height + 15 + 5 + 10;
        }
    }

    Vector2 scrollPos;

    Texture2D[] textures;

    Rect fullRect;

    void OnGUI()
    {
    
    
        Rect scrollrect = new Rect();
        scrollrect.width = position.width;
        scrollrect.height = position.height;

        scrollPos = GUI.BeginScrollView(scrollrect, scrollPos, fullRect);

        Rect r = new Rect();
        r.x = 10;

        Rect box = new Rect();
        box.x = 7;
        box.width = position.width - 30;

        foreach (Texture2D texture in textures)
        {
    
    
            box.y = r.y;
            box.height = 15 + 5 + texture.height + 2;
            GUI.Box(box, "");

            r.height = 15;
            r.width = position.width;
            //绘制名字
            GUI.Label(r, texture.name);
            r.y += r.height;

            r.y += 5;

            r.height = texture.height;
            r.width = texture.width;
            //绘制图标
            GUI.DrawTexture(r, texture);
            r.y += texture.height;

            r.y += 10;
        }
        GUI.EndScrollView();
    }
}

接下来,我们就可以看到很多见过的图标。
最好是在新建一个空项目里面,因为项目自己本身的Texture也会加载进来。

在这里插入图片描述

但是其中我发现了一些问题,有一些Texture 的 name字段是空?

在这里插入图片描述
这也行吗?但是没关系,问题不大,我们不用它们。

那现在我们看到了这些图片,怎么在我们的工具里用它们呢?这你总不能每次用它都加载,然后遍历,取名字一样的吧?

其实,Unity是有API通过名字获得具体的Icon,

	public static GUIContent IconContent (string name, string text= null);
	
	//name	所需图标的名称。
	//text	悬停在图标上的工具提示。

	//从具有给定名称的 Unity 内置资源中获取 GUIContent。
	//EditorGUIUtility.IconContent 用于为 GUI 元素创建 GUIContent。 
	//只会加载图标.通常情况下,将使用第一个参数获取 Assets/Editor Default 	Resources/Icons 中的图标。 
	//只需要图标的名称,而不需要 png 扩展名。 \ 第二个参数为悬停工具提示提供文本。
	//此字符串 需要以竖线“|”字符开头以将其标记为工具提示。
	//注意:目前无法悬停定位在工具提示上方。

要创建 GUIContent 就直接这个API就好了,那如果只是要 Texture 呢?那也很简单,

     Texture texture = EditorGUIUtility.IconContent("IconName").image;

但实际上并不是所有的Icon都可以通过这个函数取出来,这个函数能取出来的只有在 Assets/Editor Default Resoureces/Icons 里的图标。

我们改一下上面的脚本:

  /*
 * 查看所有 Textures
 * 
 * 
 * 
 */


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class UnityIconsWindow : EditorWindow
{
    
    

    [MenuItem(("JJJ/Unity Textures Window"))]
    static void Init()
    {
    
    
        UnityIconsWindow window = EditorWindow.GetWindow<UnityIconsWindow>("Unity Textures Window");
        //加载所有Texture2D
        window.textures = Resources.FindObjectsOfTypeAll<Texture2D>();
        window.minSize = new Vector2(200, 400);


        //可见
        window.textures2 = new Texture2D[window.textures.Length];
        for (int i = 0; i < window.textures2.Length; i++)
        {
    
    
            window.textures2[i] = EditorGUIUtility.IconContent(window.textures[i].name).image as Texture2D;
        }


        //用于GUI
        window.fullRect = new Rect();
        //foreach (var texture in window.textures)
        //{
    
    
        //    window.fullRect.height += texture.height + 15 + 5 + 10;
        //}
        for (int i = 0; i < window.textures2.Length; i++)
        {
    
    
            if (window.textures2[i] != null)
            {
    
    
                window.fullRect.height += window.textures2[i].height + 15 + 5 + 10;
            }
        }
    }

    Vector2 scrollPos;

    Texture2D[] textures;

    Texture2D[] textures2;

    Rect fullRect;

    void OnGUI()
    {
    
    
        Rect scrollrect = new Rect();
        scrollrect.width = position.width;
        scrollrect.height = position.height;

        scrollPos = GUI.BeginScrollView(scrollrect, scrollPos, fullRect);

        Rect r = new Rect();
        r.x = 10;

        Rect box = new Rect();
        box.x = 7;
        box.width = position.width - 30;

        foreach (Texture2D texture in textures2)
        {
    
    
            if (texture == null) continue;

            box.y = r.y;
            box.height = 15 + 5 + texture.height + 2;
            GUI.Box(box, "");

            r.height = 15;
            r.width = position.width;
            //绘制名字
            GUI.Label(r, texture.name);
            r.y += r.height;

            r.y += 5;

            r.height = texture.height;
            r.width = texture.width;
            //绘制图标
            GUI.DrawTexture(r, texture);
            r.y += texture.height;

            r.y += 10;
        }
        GUI.EndScrollView();
    }

    private void OnDisable()
    {
    
    
        textures = null;
    }
}

打开窗口:

在这里插入图片描述

从报错来看就显而易见了,要么你给个该图片的项目完整路径(包括拓展名),要么,它就必须是 Assets/Editor Default Resoureces/Icons 里的图标名字(不用拓展名)

那我们先把报错藏起来,再试一下给它个完整项目路径试试:

/*
 * 查看所有 Textures
 * 
 * 
 * 
 */


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class UnityIconsWindow : EditorWindow
{
    
    

    [MenuItem(("JJJ/Unity Textures Window"))]
    static void Init()
    {
    
    
        UnityIconsWindow window = EditorWindow.GetWindow<UnityIconsWindow>("Unity Textures Window");
        //加载所有Texture2D
        window.textures = Resources.FindObjectsOfTypeAll<Texture2D>();
        window.minSize = new Vector2(200, 400);


        //可见
        window.textures2 = new Texture2D[window.textures.Length];
        Debug.unityLogger.logEnabled = false;//关掉那个报错,不用管它
        for (int i = 0; i < window.textures2.Length; i++)
        {
    
    
            if (window.textures[i].name == "微信图片_20210808203939")//这样写很愚蠢,只是为了作为一个例子才这样写
                window.textures2[i] = EditorGUIUtility.IconContent(AssetDatabase.GetAssetPath(window.textures[i])).image as Texture2D;
            else
                window.textures2[i] = EditorGUIUtility.IconContent(window.textures[i].name).image as Texture2D;
        }
        Debug.unityLogger.logEnabled = true;

        //用于GUI
        window.fullRect = new Rect();
        //foreach (var texture in window.textures)
        //{
    
    
        //    window.fullRect.height += texture.height + 15 + 5 + 10;
        //}
        for (int i = 0; i < window.textures2.Length; i++)
        {
    
    
            if (window.textures2[i] != null)
            {
    
    
                window.fullRect.height += window.textures2[i].height + 15 + 5 + 10;
            }
        }
    }

    Vector2 scrollPos;

    Texture2D[] textures;

    Texture2D[] textures2;

    Rect fullRect;

    void OnGUI()
    {
    
    
        Rect scrollrect = new Rect();
        scrollrect.width = position.width;
        scrollrect.height = position.height;

        scrollPos = GUI.BeginScrollView(scrollrect, scrollPos, fullRect);

        Rect r = new Rect();
        r.x = 10;

        Rect box = new Rect();
        box.x = 7;
        box.width = position.width - 30;

        foreach (Texture2D texture in textures2)
        {
    
    
            if (texture == null) continue;

            box.y = r.y;
            box.height = 15 + 5 + texture.height + 2;
            GUI.Box(box, "");

            r.height = 15;
            r.width = position.width;
            //绘制名字
            GUI.Label(r, texture.name);
            r.y += r.height;

            r.y += 5;

            r.height = texture.height;
            r.width = texture.width;
            //绘制图标
            GUI.DrawTexture(r, texture);
            r.y += texture.height;

            r.y += 10;
        }
        GUI.EndScrollView();
    }

    private void OnDisable()
    {
    
    
        textures = null;
    }
}

再打开窗口:

在这里插入图片描述
完美,可以看到第一个就是了。

那我们就可以考虑有这样一个工具类,当我们需要Icon时,只需要通过这个脚本就可以。

using UnityEngine;
using UnityEditor;

public static class JIconUtility
{
    
    
    //比如需要一个文件夹图标,就可以这样写
    static Texture2D directoryIcon;
    public static Texture2D DirectoryIcon {
    
     get {
    
     if (directoryIcon == null) directoryIcon = EditorGUIUtility.IconContent("Folder Icon").image as Texture2D; return directoryIcon; } }

    //其他的你自定义的icon其实也可以放在这里,只不过不是用 EditorGUIUtility.IconContent() ,而是要直接 Resources.Load 加载
    static Texture2D myIcon;
    public static Texture2D MyIcon {
    
     get {
    
     if (myIcon == null) myIcon = Resources.Load<Texture2D>("MyIcon"/*自定义icon路径*/); return myIcon; } }
}

或者你也可以用 EditorGUIUtility.Load() 或者 EditorGUIUtility.LoadRequired() 来加载内置资源。

猜你喜欢

转载自blog.csdn.net/weixin_44293055/article/details/120443635
今日推荐