[Unity工具]使用TexturePacker自动打包图集

前言:

在使用Unity构建UI时,我们时常需要构建图集去优化DrawCall,如果美术频繁的修改图片,需要我们多次去修改图集,因此需要一个自动打包图集的工具去做这样一个重复的工作。

**工具:**TexturePackerUnity

**第一步:**使用TexturePacker将图片打包成图集,根据工程去配置下面代码里面的路径,然后调用Build方法开始自动打包

using System.Diagnostics;
using System.IO;
using System.Text;
using UnityEditor;
using Debug = UnityEngine.Debug;

public class AutoTPBuild : Editor
{
    //图集的输出路径(打出的图集放在哪个文件夹)
    private const string TP_OUT_PATH = "";

    //TexturePacker.exe所在位置
    private const string TEXTURE_PACKER_EXE_PATH = "";

    //记录打出的图集的大小的文件夹,用作后续使用,可一键设置图集的IOS和Android的格式
    private const string SIZE_PATH = "";

    /// <summary>
    /// 一个文件夹下的多个子文件夹里面的图片打成多个图集
    /// </summary>
    /// <param name="_sourceTexturePath">传入的需要打包的图片路径</param> 
    public static void Build(string _sourceTexturePath)
    {
        if (File.Exists(SIZE_PATH))
        {
            File.Delete(SIZE_PATH);
        }

        if (!Directory.Exists(TP_OUT_PATH))
        {
            Directory.CreateDirectory(TP_OUT_PATH);
            AssetDatabase.Refresh();
        }
        
        var folders = Directory.GetDirectories(_sourceTexturePath);
        
        foreach (var folder in folders)
        {
            //图集名字
            var name = Path.GetFileName(folder);
            //图集的输出路径,带图集名
            var sheetPath = $"{TP_OUT_PATH}/{name}"+"{n1}";
            var info = GetStartInfo(TEXTURE_PACKER_EXE_PATH, GetCommand(sheetPath, folder));
            ExecuteProcess(info,name);
        }

        AssetDatabase.Refresh();
        Debug.LogError("构建图集成功");
    }
    
    /// <summary>
    /// 打图集的所需的命令行
    /// </summary>
    /// <param name="sheetPath">图集的输出路径,带图集名</param>
    /// <param name="folderPath">图片所在文件夹的路径</param>
    /// <returns></returns>
    private static string GetCommand(string sheetPath,string folderPath)
    {
        var sb = new StringBuilder();
        AddSubCommand(sb, $"--sheet {sheetPath}.png");
        AddSubCommand(sb, $"--data {sheetPath}.tpsheet");
        AddSubCommand(sb, "--format unity-texture2d");
        AddSubCommand(sb, "--trim-mode Polygon");
        AddSubCommand(sb, "--algorithm Polygon");
        AddSubCommand(sb, "--max-size 4096");
        AddSubCommand(sb, "--multipack");
        AddSubCommand(sb, "--size-constraints POT");
        AddSubCommand(sb, $"{folderPath}");
        return sb.ToString();
    }
    
    /// <summary>
    /// 添加命令行
    /// </summary>
    private static void AddSubCommand(StringBuilder sb,string command)
    {
        sb.Append(" ");
        sb.Append(command);
    }

    /// <summary>
    /// 返回一个执行TexturePacker.exe的带有打图集命令的进程
    /// </summary>
    /// <param name="exePath">TexturePacker的存放路径</param>
    /// <param name="command">命令</param>
    /// <returns></returns>
    private static ProcessStartInfo GetStartInfo(string exePath, string command)
    {
        var info = new ProcessStartInfo(exePath)
        {
            Arguments = command,
            ErrorDialog = true,
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true
        };
        return info;
    }

    /// <summary>
    /// 执行打图集的进程
    /// </summary>
    /// <param name="info"></param>
    private static void ExecuteProcess(ProcessStartInfo info,string fileName)
    {
        var process = Process.Start(info);

        #region 记录打出的图集的分辨率。用于后续设置文件的IOS和Android格式

        //构建一个图集的输出信息
        var outPutInfo = process.StandardOutput.ReadToEnd();
        var textTureSize = outPutInfo.Contains("4096") ? "4096" : "2048";
        //将打的图集的大小记录在文件中
        if (File.Exists(SIZE_PATH))
        {
            using var fs = File.Open(SIZE_PATH, FileMode.Append);
            var b =  Encoding.UTF8.GetBytes("#"+fileName+"&"+textTureSize);
            fs.Write(b,0,b.Length);
        }
        else
        {
            File.Create(SIZE_PATH).Dispose();
            using var fs = File.Open(SIZE_PATH, FileMode.Append);
            var b =  Encoding.UTF8.GetBytes("#"+fileName+"&"+textTureSize);
            fs.Write(b,0,b.Length);
        }

        #endregion
        
        var error = process.StandardError.ReadToEnd();
        if (!string.IsNullOrEmpty(error))
        {
            Debug.LogError(error);
        }
        
        process.Close();
    }
}


**第一步:**根据上面打包出来的图集会生成一个名为“size”的文本,里面记录了每个图集的大小,配置好路径可以使用下面代码自动设置图集的大小和格式

using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
public class SetSpriteAltasFormatAndSize : Editor
{
  //需要转换格式的图集的路径
  private const string SPRITES_PATH = "";

  //记录每个图集大小的文本文件
  private const string SIZE_PATH = "";

  public static void SetAllSpriteFormat()
  {
    //得到记录的图集的大小
    Dictionary<string, int> sizeDict = new Dictionary<string, int>();
    var allText = File.ReadAllText(SIZE_PATH);
    var info = allText.Split('#');
    foreach (var t in info)
    {
      var singleInfo = t.Split('&');
      if (singleInfo.Length >= 2)
      {
        if (int.TryParse(singleInfo[1], out var size))
        {
          if (!sizeDict.ContainsKey(singleInfo[0]))
          {
            sizeDict.Add(singleInfo[0], size);
          }
        }
      }
    }

    var directoryInfo = new DirectoryInfo(SPRITES_PATH);
    var fileInfos = directoryInfo.GetFiles("*.png");

    EditorApplication.update = delegate()
    {
      for (int i = 0; i < fileInfos.Length; i++)
      {
        string str = fileInfos[i].Name.Replace(".png", "");
        str = str.Substring(0, str.Length - 1);
        var newPath = SPRITES_PATH + "/" + fileInfos[i].Name;
        var maxSize = 2048;
        if (sizeDict.ContainsKey(str))
        {
          maxSize = sizeDict[str];
        }
        else
        {
          Debug.LogError("找不到该图片应该设置大小为多少" + fileInfos[i].Name);
        }

        var isCancel = EditorUtility.DisplayCancelableProgressBar("执行中...", newPath, (float)i / fileInfos.Length);
        if (isCancel)
        {
          break;
        }

        TextureImporter textureIm = AssetImporter.GetAtPath(newPath) as TextureImporter;
        if (null != textureIm)
        {
          //设置android平台
          var androidSetting = new TextureImporterPlatformSettings
          {
            overridden = true,
            name = "Android",
            maxTextureSize = maxSize,
            format = TextureImporterFormat.ETC2_RGBA8
          };
          textureIm.SetPlatformTextureSettings(androidSetting);

          //设置Ios平台
          var iosSetting = new TextureImporterPlatformSettings
          {
            overridden = true,
            name = "iPhone",
            maxTextureSize = maxSize,
            format = TextureImporterFormat.ETC2_RGBA8
          };
          textureIm.SetPlatformTextureSettings(iosSetting);

          textureIm.SaveAndReimport();
          AssetDatabase.ImportAsset(newPath);
        }
      }
      EditorUtility.ClearProgressBar();
      EditorApplication.update = null;
      AssetDatabase.Refresh();

      Debug.LogError("设置图集的IOS和Android成功");
    };
  }
}

猜你喜欢

转载自blog.csdn.net/lel18570471704/article/details/134708887