Unity中批量修改图片导入设置及修改图集的设置

目的:

一.  导入资源设置

二.   导入时设置图片

三.   设置图集的大小


目的:

一般我们在Unity中使用图片的时候,导入图片的时候都会采取默认设置,如果我们使用Atlas(图集)功能的话,会将好多张图片按照一定大小放到一张图集中去,如果图片多了,有可能图集大小就会过大,然而当当当,在图片的导入设置中有这么一项,MaxSize,这个参数决定了当前图集允许的最大大小,现在碰到这么一个需求,需要修改所有项目中图片的这个设置为固定大小,如果一个个图片去设置,那真的是一个庞大的工作量,这时候强大的度娘就派上用场了,在大量API文档和各种例子中取其精华去其糟粕,获得了一个这样的工具,根据文件夹路径修改所有图片的导入设置为可选配置的值,具体内容就让我们一起来看看吧,啊哈哈。


一.  导入资源设置

首先看看导入设置是个什么鬼,见下图

这时候我们需要修改的参数就是Default中的MaxSize,

 滴滴滴 注意长代码来袭,精华所在。

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

public class AtlasSetting : EditorWindow
{
    /// <summary>
    /// 纹理最大大小
    /// </summary>
    int m_nTexMaxSize = 1024;
    /// <summary>
    /// 是否重写其他设置(PC,安卓,IOS)
    /// </summary>
    bool m_bIsOverride = true;
    /// <summary>
    /// 默认纹理导入格式
    /// </summary>
    TextureImporterFormat m_nDefaultPlatformImporterFormat=TextureImporterFormat.Automatic;
    /// <summary>
    /// 安卓平台纹理导入格式
    /// </summary>
    TextureImporterFormat m_nAndroidPlatformImporterFormat=TextureImporterFormat.Automatic;
    /// <summary>
    /// PC纹理导入格式
    /// </summary>
    TextureImporterFormat m_nPCPlatformImporterFormat=TextureImporterFormat.Automatic;
    /// <summary>
    /// 苹果纹理导入格式
    /// </summary>
    TextureImporterFormat m_nIphonePlatformImporterFormat=TextureImporterFormat.Automatic;
    /// <summary>
    /// 纹理压缩质量
    /// </summary>
    TextureImporterCompression m_nImporterCompression = TextureImporterCompression.Compressed;

    [MenuItem("Tools/AtlasSetting")]
    static void ChangeTextureSetting()
    {
        //创建窗口
        Rect window = new Rect(500, 500, 500, 500);
        AtlasSetting setting = (AtlasSetting)EditorWindow.GetWindowWithRect(typeof(AtlasSetting), window, false, "AtlasSetting");
        setting.Show();
    }
    private void OnGUI()
    {
        EditorGUILayout.Space();//空一行
        EditorGUILayout.LabelField("修改纹理的设置",new GUIStyle() { alignment=TextAnchor.MiddleCenter, fontSize=16},GUILayout.Height(30));
        EditorGUILayout.Space();//空一行
        m_nTexMaxSize = int.Parse(EditorGUILayout.TextField("Sprite Max Size","1024"));
        EditorGUILayout.Space();//空一行
        m_bIsOverride = EditorGUILayout.Toggle("Is Override Other Device",true);
        EditorGUILayout.Space();//空一行
        m_nDefaultPlatformImporterFormat = (TextureImporterFormat)EditorGUILayout.EnumPopup("Default", m_nDefaultPlatformImporterFormat);
        EditorGUILayout.Space();//空一行
        m_nPCPlatformImporterFormat = (TextureImporterFormat)EditorGUILayout.EnumPopup(" PC", m_nPCPlatformImporterFormat);
        EditorGUILayout.Space();//空一行
        m_nAndroidPlatformImporterFormat = (TextureImporterFormat)EditorGUILayout.EnumPopup("Android", m_nAndroidPlatformImporterFormat);
        EditorGUILayout.Space();//空一行
        m_nIphonePlatformImporterFormat = (TextureImporterFormat)EditorGUILayout.EnumPopup("Iphone", m_nIphonePlatformImporterFormat);
        EditorGUILayout.Space();//空一行
        if (GUILayout.Button("开始设置", GUILayout.ExpandWidth(true),GUILayout.Height(50)))
        {
            EditorUtility.DisplayProgressBar("Loading", "in progress", m_fSliderValue);
            ChangeAllFileSetting();
        }
    }
    bool m_bIsShowProgressBar = false;
    float m_fSliderValue = 0;
    /// <summary>
    /// 此方法弃用
    /// </summary>
    static void StartSetting()
    {
        //var a = Packer.atlasNames;
        //var b = Packer.GetTexturesForAtlas(a[0]);
        //SpriteAtlas atlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>(path);
        //var c = Packer.GetAlphaTexturesForAtlas(a[1]);
        //var d =Packer.
        //SpriteAtlasExtensions.GetTextureSettings()
        //Debug.Log(a.Length.ToString());
    }
    /// <summary>
    /// 按钮点击的时候开始改变文件设置
    /// </summary>
    void ChangeAllFileSetting()
    {
        imageCount = 0;
        string filePath = GetSpritePath();
        DirectoryInfo dirInfo = new DirectoryInfo(filePath);
        CheckDirectory(dirInfo);
        var flag = EditorUtility.DisplayDialog("修改完成", $"共修改了{imageCount}个图片", "完成");
        EditorUtility.ClearProgressBar();
    }
    int imageCount = 0;
    /// <summary>
    /// 这里使用一个迭代函数来处理所有文件夹里面嵌套的文件夹内容
    /// </summary>
    /// <param name="directoryInfo"></param>
    void CheckDirectory(DirectoryInfo directoryInfo)
    {
        DirectoryInfo[] infos = directoryInfo.GetDirectories();
        for (int i = 0,length=infos.Length; i < length; i++)
        {
            CheckDirectory(infos[i]);
            //break;
        }
        FileInfo[] files = directoryInfo.GetFiles();
        ChangeSettingByFolder(files);
    }
    /// <summary>
    /// 改变文件数组中所有文件的设置
    /// </summary>
    /// <param name="files"></param>
    void ChangeSettingByFolder(FileInfo[] files)
    {
        for (int i = 0, length = files.Length; i < length; i++)
        {
            if (!files[i].Name.Contains("meta"))
            {
                string onePath = GetImageProjectPath(files[i].FullName);
                TextureImporter m_pImporter = AssetImporter.GetAtPath(onePath) as TextureImporter;
                if (m_pImporter == null)
                    continue;
                ChangeTextureSetting(m_pImporter);
                imageCount++;
                m_fSliderValue = imageCount * 1.0f / 3000;
                EditorUtility.DisplayProgressBar("Loading", "in progress", m_fSliderValue);
            }
        }
    }
    /// <summary>
    /// 根据固定字符串得到资源路径
    /// </summary>
    /// <param name="fullName"></param>
    /// <returns></returns>
    string GetImageProjectPath(string fullName)
    {
        string result = "";
        int index = fullName.LastIndexOf("Assets");
        result = fullName.Substring(index, fullName.Length- index);
        return result;
    }
    /// <summary>
    /// 改变纹理设置
    /// </summary>
    /// <param name="textureImporter"></param>
    void ChangeTextureSetting(TextureImporter textureImporter)
    {
        if (textureImporter == null)
        {
            Debug.LogError("获取设置失败");
            return;
        }
        ChangeDefaultSetting(textureImporter);
        ChangePCSetting(textureImporter);
        ChangeIphoneSetting(textureImporter);
        ChangeAndroidSetting(textureImporter);
        textureImporter.SaveAndReimport();
    }
    /// <summary>
    /// 修改默认设置
    /// </summary>
    /// <param name="textureImporter"></param>
    void ChangeDefaultSetting(TextureImporter textureImporter)
    {
        TextureImporterPlatformSettings defaultSetting = textureImporter.GetDefaultPlatformTextureSettings();
        defaultSetting.maxTextureSize = m_nTexMaxSize;
        //defaultSetting.compressionQuality = defaultSetting.compressionQuality;
        defaultSetting.crunchedCompression = false;
        defaultSetting.textureCompression = m_nImporterCompression;
        defaultSetting.format = m_nDefaultPlatformImporterFormat;
        textureImporter.SetPlatformTextureSettings(defaultSetting);
    }
    /// <summary>
    /// 设置所有的设备
    /// </summary>
    /// <param name="platformSettings"></param>
    void SetTextureValue(TextureImporterPlatformSettings platformSettings)
    {
        platformSettings.maxTextureSize = m_nTexMaxSize;
        platformSettings.overridden = m_bIsOverride;
    }
    /// <summary>
    /// 修改PC设置
    /// </summary>
    /// <param name="textureImporter"></param>
    void ChangePCSetting(TextureImporter textureImporter)
    {
        TextureImporterPlatformSettings pcSetting = textureImporter.GetPlatformTextureSettings("Standalone");
        SetTextureValue(pcSetting);
        pcSetting.format = m_nPCPlatformImporterFormat;
        textureImporter.SetPlatformTextureSettings(pcSetting);
    }
    /// <summary>
    /// 修改安卓设置
    /// </summary>
    /// <param name="textureImporter"></param>
    void ChangeAndroidSetting(TextureImporter textureImporter)
    {
        TextureImporterPlatformSettings androidSetting = textureImporter.GetPlatformTextureSettings("Android");
        SetTextureValue(androidSetting);
        androidSetting.format = m_nAndroidPlatformImporterFormat;
        textureImporter.SetPlatformTextureSettings(androidSetting);
    }
    /// <summary>
    /// 修改ios设置
    /// </summary>
    /// <param name="textureImporter"></param>
    void ChangeIphoneSetting(TextureImporter textureImporter)
    {
        TextureImporterPlatformSettings iphoneSetting = textureImporter.GetPlatformTextureSettings("Iphone");
        SetTextureValue(iphoneSetting);
        iphoneSetting.format = m_nIphonePlatformImporterFormat;
        textureImporter.SetPlatformTextureSettings(iphoneSetting);
    }
    static string GetSpritePath()
    {
        string streamPath = Application.streamingAssetsPath;
        string parentPath=streamPath.Substring(0, streamPath.LastIndexOf('/'));
        string resultPath = Path.Combine(parentPath, "自己的文件路径");
        return resultPath;
    }
}

这里有几点需要注意:

1.        GetPlatformTextureSettings通过这个接口获取的不同平台的设置对应图片中所示的内容设置

 2.        在修改设置值之后需要调用TextureImporter.SaveAndReimport()这个方法来使修改的设置生效,并重新导入。

OK大功告成,需要修改其他参数可以参考官方文档的关于TextureImporter这个类的说明。官方说明

这个导入设置还有上半部分的设置也可以通过脚本修改,但是没有试过,有需要的小伙伴可以自己去摸索摸索,这里提示可以通过TextureImporter.ReadTextureSettings()获取纹理设置,之后修改对应参数,在通过TextureImporter.SetTextureSettings()去使设置生效。具体能否成功,各位看官自行验证吧!!!

二.   导入时设置图片

在导入时设置图片,Unity为我们提供了一个API(AssetPostprocessor),这里面有我们要用的东西。见代码:

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

public class TextureImporterSetting : AssetPostprocessor
{
    //----------------导入设置----------
    /// <summary>
    /// 纹理最大大小
    /// </summary>
    int m_nTexMaxSize = 1024;
    /// <summary>
    /// 是否重写其他设置(PC,安卓,IOS)
    /// </summary>
    bool m_bIsOverride = true;
    /// <summary>
    /// 格式
    /// </summary>
    TextureImporterFormat formatSetting = TextureImporterFormat.Automatic;
    /// <summary>
    /// 压缩质量
    /// </summary>
    TextureImporterCompression qualitySetting = TextureImporterCompression.Compressed;
    /// <summary>
    /// 当一个texture2D在Unity压缩它之前完成导入时,会调用这个函数
    /// </summary>
    void OnPreprocessTexture()
    {
        TextureImporter textureImporter=assetImporter as TextureImporter;
        if (textureImporter != null)
        {
            ChangeSpriteSetting(textureImporter);
        }
    }
    void ChangeSpriteSetting(TextureImporter textureImporter)
    {
        ChangeDefaultSetting(textureImporter);
        ChangePCSetting(textureImporter);
        ChangeIphoneSetting(textureImporter);
        ChangeAndroidSetting(textureImporter);
    }
    /// <summary>
    /// 修改默认设置
    /// </summary>
    /// <param name="textureImporter"></param>
    void ChangeDefaultSetting(TextureImporter textureImporter)
    {
        TextureImporterPlatformSettings defaultSetting = textureImporter.GetDefaultPlatformTextureSettings();
        defaultSetting.maxTextureSize = m_nTexMaxSize;
        //defaultSetting.compressionQuality = defaultSetting.compressionQuality;
        defaultSetting.crunchedCompression = false;
        defaultSetting.textureCompression = qualitySetting;
        defaultSetting.format = formatSetting;
        textureImporter.SetPlatformTextureSettings(defaultSetting);
    }
    /// <summary>
    /// 设置所有的设备
    /// </summary>
    /// <param name="platformSettings"></param>
    void SetTextureValue(TextureImporterPlatformSettings platformSettings)
    {
        platformSettings.maxTextureSize = m_nTexMaxSize;
        platformSettings.overridden = m_bIsOverride;
    }
    /// <summary>
    /// 修改PC设置
    /// </summary>
    /// <param name="textureImporter"></param>
    void ChangePCSetting(TextureImporter textureImporter)
    {
        TextureImporterPlatformSettings pcSetting = textureImporter.GetPlatformTextureSettings("Standalone");
        SetTextureValue(pcSetting);
        pcSetting.format = formatSetting;
        textureImporter.SetPlatformTextureSettings(pcSetting);
    }
    /// <summary>
    /// 修改安卓设置
    /// </summary>
    /// <param name="textureImporter"></param>
    void ChangeAndroidSetting(TextureImporter textureImporter)
    {
        TextureImporterPlatformSettings androidSetting = textureImporter.GetPlatformTextureSettings("Android");
        SetTextureValue(androidSetting);
        androidSetting.format = formatSetting;
        textureImporter.SetPlatformTextureSettings(androidSetting);
    }
    /// <summary>
    /// 修改ios设置
    /// </summary>
    /// <param name="textureImporter"></param>
    void ChangeIphoneSetting(TextureImporter textureImporter)
    {
        TextureImporterPlatformSettings iphoneSetting = textureImporter.GetPlatformTextureSettings("Iphone");
        SetTextureValue(iphoneSetting);
        iphoneSetting.format = formatSetting;
        textureImporter.SetPlatformTextureSettings(iphoneSetting);
    }
}

三.   设置图集的大小

以上修改了图片的设置,但是在项目中我们往往还会碰到修改图集的需求,尤其在后期项目做优化的时候,对图集的管理就更加至关重要了,后来发现雨松的一篇文章对此进行实现,在这里也分享一下,同时自己也记录一下,后面用到方便。o(* ̄▽ ̄*)ブ

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

// DefaultPackerPolicy will pack rectangles no matter what Sprite mesh type is unless their packing tag contains "[TIGHT]".
class CustomAtlasPolicy : UnityEditor.Sprites.IPackerPolicy
{
	protected class Entry
	{
		public Sprite sprite;
		public AtlasSettings settings;
		public string atlasName;
		public SpritePackingMode packingMode;
	}

	public virtual int GetVersion() { return 1; }

	protected virtual string TagPrefix { get { return "[TIGHT]"; } }
	protected virtual bool AllowTightWhenTagged { get { return true; } }

    public bool AllowSequentialPacking => true;

    public void OnGroupAtlases(BuildTarget target, PackerJob job, int[] textureImporterInstanceIDs)
	{
		List<Entry> entries = new List<Entry>();

		foreach (int instanceID in textureImporterInstanceIDs)
		{
			TextureImporter ti = EditorUtility.InstanceIDToObject(instanceID) as TextureImporter;

			TextureFormat desiredFormat;
			ColorSpace colorSpace;
			int compressionQuality;
			ti.ReadTextureImportInstructions(target, out desiredFormat, out colorSpace, out compressionQuality);

			TextureImporterSettings tis = new TextureImporterSettings();
			ti.ReadTextureSettings(tis);

			Sprite[] sprites = AssetDatabase.LoadAllAssetRepresentationsAtPath(ti.assetPath).Select(x => x as Sprite).Where(x => x != null).ToArray();
			foreach (Sprite sprite in sprites)
			{
				//在这里设置每个图集的参数
				Entry entry = new Entry();
				entry.sprite = sprite;
				entry.settings.format = desiredFormat;
				//entry.settings.usageMode = ins.usageMode;
				entry.settings.colorSpace = colorSpace;
				entry.settings.compressionQuality = compressionQuality;
				entry.settings.filterMode = Enum.IsDefined(typeof(FilterMode), ti.filterMode) ? ti.filterMode : FilterMode.Bilinear;
				entry.settings.maxWidth = 1024;
				entry.settings.maxHeight = 1024;
				entry.atlasName = ParseAtlasName(ti.spritePackingTag);
				entry.packingMode = GetPackingMode(ti.spritePackingTag, tis.spriteMeshType);

				entries.Add(entry);
			}

			Resources.UnloadAsset(ti);
		}

		// First split sprites into groups based on atlas name
		var atlasGroups =
			from e in entries
			group e by e.atlasName;
		foreach (var atlasGroup in atlasGroups)
		{
			int page = 0;
			// Then split those groups into smaller groups based on texture settings
			var settingsGroups =
				from t in atlasGroup
				group t by t.settings;
			foreach (var settingsGroup in settingsGroups)
			{
				string atlasName = atlasGroup.Key;
				if (settingsGroups.Count() > 1)
					atlasName += string.Format(" (Group {0})", page);

				job.AddAtlas(atlasName, settingsGroup.Key);
				foreach (Entry entry in settingsGroup)
				{
					job.AssignToAtlas(atlasName, entry.sprite, entry.packingMode, SpritePackingRotation.None);
				}

				++page;
			}
		}
	}

	protected bool IsTagPrefixed(string packingTag)
	{
		packingTag = packingTag.Trim();
		if (packingTag.Length < TagPrefix.Length)
			return false;
		return (packingTag.Substring(0, TagPrefix.Length) == TagPrefix);
	}

	private string ParseAtlasName(string packingTag)
	{
		string name = packingTag.Trim();
		if (IsTagPrefixed(name))
			name = name.Substring(TagPrefix.Length).Trim();
		return (name.Length == 0) ? "(unnamed)" : name;
	}

	private SpritePackingMode GetPackingMode(string packingTag, SpriteMeshType meshType)
	{
		if (meshType == SpriteMeshType.Tight)
			if (IsTagPrefixed(packingTag) == AllowTightWhenTagged)
				return SpritePackingMode.Tight;
		return SpritePackingMode.Rectangle;
	}
}

此脚本转载于雨松博客,地址:雨松博客

猜你喜欢

转载自blog.csdn.net/a1191835397/article/details/127985113
今日推荐