最近项目升级使用2018,突然发现2018的Icon设置变得复杂了起来(其实就是多了几个),如果想设置其余类型的Icon应该怎么操作,网上查了一些有用没用的,自己去官方API看了看之后整理了一下,在这里综合贴出来。

先展示下在下Icon的存放路径

unity 控件样式图标不显示 unity icon设置_unity 控件样式图标不显示

原本在Unity2017设置Android端Icon相当简单,在这里直接贴上代码先

public class AutoIconSet : Editor
{
    private static readonly string Icon_Path = @"Assets\Arts\Icons\{0}\{1}.png";

    [MenuItem("IconSet/App")]
    public static void SetAppIcons()
    {
        SetIcons("APP");
    }

    private static void SetIcons(string iconPrefixName)
    {
        //获取所有的Icon尺寸
        int[] iconSizes = PlayerSettings.GetIconSizesForTargetGroup(BuildTargetGroup.Android);
        Texture2D[] texArray = new Texture2D[iconSizes.Length];
        for (int i = 0; i < iconSizes.Length; ++i)
        {
            int iconSize = iconSizes[i];
            //获得对应目录下的Icon,并转换成Texture2D
            Texture2D tex2D = AssetDatabase.LoadAssetAtPath(string.Format(Icon_Path, iconPrefixName, iconSize),
                typeof(Texture2D)) as Texture2D;
            texArray[i] = tex2D;
        }
        //设置到PlayerSettings的各个Icon上
        PlayerSettings.SetIconsForTargetGroup(BuildTargetGroup.Android, texArray);

        AssetDatabase.SaveAssets();
        Debug.LogFormat("Set {0} Icon Complete", iconPrefixName);
    }
}

以前2017的设置就完成了(2017Unity已经被我卸载了,所以贴图就贴不了了),今天我们主要看看2018。

(原本的代码其实也可以用,会默认设置到2018的Legacy类型的Icon中)

2018的Icon设置是这样的,与图:

unity 控件样式图标不显示 unity icon设置_unity 控件样式图标不显示_02

展开后,

unity 控件样式图标不显示 unity icon设置_一键设置Icon_03

unity 控件样式图标不显示 unity icon设置_unity 控件样式图标不显示_04

unity 控件样式图标不显示 unity icon设置_一键设置Icon_05

第一个相当长,没截图完毕,浏览一下自己的Unity设置就能看到了。

就图来看,也就是说,新版的2018需要设置3种类型的Icon,那么需要如何设置呢,现在把代码放上去。

public class AutoIconSet : Editor
{
    //必须和存放Icon的文件夹路径一直,否则获得的Texture2D将会为空
    private static readonly string Icon_Path = @"Assets\Arts\Icons\{0}\{1}.png";

    [MenuItem("IconSet/App")]
    public static void SetAppIcons()
    {
        SetIcons("APP");
    }

    private static void SetIcons(string iconPrefixName)
    {
        int[] iconSizes = PlayerSettings.GetIconSizesForTargetGroup(BuildTargetGroup.Android);
        Texture2D[] texArray = new Texture2D[iconSizes.Length];
        for (int i = 0; i < iconSizes.Length; ++i)
        {
            int iconSize = iconSizes[i];
            Texture2D tex2D = AssetDatabase.LoadAssetAtPath(string.Format(Icon_Path, iconPrefixName, iconSize),
                typeof(Texture2D)) as Texture2D;
            texArray[i] = tex2D;
        }

        //此处为新API
        var platform = BuildTargetGroup.Android;
        //kind有3种,分别对应PlayerSettings的Legacy,Round,Adaptive
        var kind = UnityEditor.Android.AndroidPlatformIconKind.Round;
        var icons = PlayerSettings.GetPlatformIcons(platform, kind);

        for (int i = 0, length = icons.Length; i < length; ++i)
        {
            //将转换后获得的Texture2D数组,逐个赋值给icons
            icons[i].SetTexture(texArray[i]);
        }
        PlayerSettings.SetPlatformIcons(platform, kind, icons);
        //新API结束

        AssetDatabase.SaveAssets();
        Debug.LogFormat("Set {0} Icon Complete", iconPrefixName);
    }
}

这样Unity窗口上就会有

unity 控件样式图标不显示 unity icon设置_Icon设置_06

,点击一下App,就能自动为自己的项目设置Icon了。此外,如果出现Set Icon Complete的log,但是却看不见PlayerSettings里有显示,可以检查一下Icon的存放路径和脚本里的Icon_Path是否填写一致。

=====================分割线==================

很快就根据Android,IOS平台之分,以及N种Icon类型,修改了这个脚本,使得脚本可以由外部自由选择来决定平台和Icon类型

同时不再由代码设置文件夹,需要自己根据Unity的要求创建相应的文件夹,这样保证一一对应,来对Icon进行设置

文件夹展示:

unity 控件样式图标不显示 unity icon设置_一键设置Icon_07

脚本的话,进行如下增删:

using UnityEngine;
using UnityEditor;
using System.IO;

public class AutoIconSet : Editor
{
    private static readonly string Icon_Path = @"Assets\Arts\Icons\{0}\{1}\{2}.png";

    [MenuItem("IconSet/Android/Adaptive")]
    public static void SetAndroidAdaptive()
    {
        SetIcons(BuildTargetGroup.Android, UnityEditor.Android.AndroidPlatformIconKind.Adaptive);
    }

    [MenuItem("IconSet/Android/Round")]
    public static void SetAndroidRound()
    {
        SetIcons(BuildTargetGroup.Android, UnityEditor.Android.AndroidPlatformIconKind.Round);
    }
        
    [MenuItem("IconSet/Android/Legacy")]
    public static void SetAndroidLegacy()
    {       
        SetIcons(BuildTargetGroup.Android, UnityEditor.Android.AndroidPlatformIconKind.Legacy);
    }

    [MenuItem("IconSet/iOS/Application")]
    public static void SetiOSApplication()
    {
        SetIcons(BuildTargetGroup.iOS, UnityEditor.iOS.iOSPlatformIconKind.Application);
    }

    [MenuItem("IconSet/iOS/Spotlight")]
    public static void SetiOSSpotlight()
    {
        SetIcons(BuildTargetGroup.iOS, UnityEditor.iOS.iOSPlatformIconKind.Spotlight);
    }

    [MenuItem("IconSet/iOS/Settings")]
    public static void SetiOSSettings()
    {
        SetIcons(BuildTargetGroup.iOS, UnityEditor.iOS.iOSPlatformIconKind.Settings);
    }

    [MenuItem("IconSet/iOS/Notifications")]
    public static void SetiOSNotifications()
    {
        SetIcons(BuildTargetGroup.iOS, UnityEditor.iOS.iOSPlatformIconKind.Notification);
    }

    [MenuItem("IconSet/iOS/Marketing")]
    public static void SetiOSMarketing()
    {
        SetIcons(BuildTargetGroup.iOS, UnityEditor.iOS.iOSPlatformIconKind.Marketing);
    }

    private static Texture2D[] GetIconsFromAsset(BuildTargetGroup target, PlatformIconKind kind, PlatformIcon[] icons)
    {
        Texture2D[] texArray = new Texture2D[icons.Length];

        //因为Android设置会带有" API (xx)"等附加信息,为了文件夹不出现空格,只取空格前单词
        string folder = kind.ToString().Split(' ')[0];
        string filename;
        for (int i = 0; i < texArray.Length; ++i)
        {
            //不需要再通过GetIconSizesForTargetGroup了来获得Icon尺寸数组,
            //直接由对应的PlatformIcon.width来获取Icon大小
            int iconSize = icons[i].width;
            filename = string.Format(Icon_Path, target, folder, iconSize);
            if (!File.Exists(filename))
            {
                Debug.LogErrorFormat("图片文件不存在, 路径为:{0}", filename);
                continue;
            }
            Texture2D tex2D = AssetDatabase.LoadAssetAtPath(filename,
                typeof(Texture2D)) as Texture2D;
            texArray[i] = tex2D;
        }
        return texArray;
    }

    private static void SetIcons(BuildTargetGroup platform, PlatformIconKind kind)
    {
        //获得当前平台和当前Icon类型的PlatformIcon数组
        PlatformIcon[] icons = PlayerSettings.GetPlatformIcons(platform, kind);

        //将Asset转为Texture2D
        Texture2D[] iconSources = GetIconsFromAsset(platform, kind, icons);

        for (int i = 0, length = icons.Length; i < length; ++i)
        {
            icons[i].SetTexture(iconSources[i]);
        }

        PlayerSettings.SetPlatformIcons(platform, kind, icons);

        AssetDatabase.SaveAssets();
        Debug.LogFormat("Set {0}/{1} Icon Complete", platform,  kind);
    }
}

这样,通过自己编写Editor函数来选择平台和Icon类型,使得代码更加灵活。如图:

unity 控件样式图标不显示 unity icon设置_Unity_08

unity 控件样式图标不显示 unity icon设置_ico_09

有错误欢迎指出啊!