TexturePacker 可以通过命令行方式,批量生成图集,TexturePacker相关命令可以参考 https://blog.csdn.net/u014065445/article/details/54289787
unity中使用的方式是,通过C#中的Process类,创建一个独立进程,执行命令行脚本,完成图集生成和切分
Mac平台的shell脚本
./TexturePacker \
--sheet $3/$1_{n}.png \
--data $3/$1_{n}.txt $2 \
--format unity \
--trim-sprite-names \
--basic-sort-by Name \
--basic-order Descending \
--max-size $4 \
--size-constraints POT \
--force-squared \
--border-padding 1 \
--shape-padding 2 \
--disable-rotation \
--trim-mode None \
--disable-auto-alias \
--multipack
Windows平台的bat脚本
@echo off
start TexturePacker.exe %2 --sheet %3/%1_{n}.png --data %3/%1_{n}.txt %2 ^
--format unity --trim-sprite-names --basic-sort-by Name --basic-order Descending ^
--max-size %4 --size-constraints POT --force-squared --border-padding 1 --shape-padding 2 ^
--disable-rotation --trim-mode None --disable-auto-alias --multipack --extrude 0
unity编辑器脚本
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Diagnostics;
using System;
using System.Text;
using LitJson;
public class BuildAtlasToolEditor {
public static string spriteFolder = "Assets/AssetBundleData/Image";
public static string atlasFolder = "Assets/AssetBundleData/UI/Atlas";
[MenuItem("Assets/Build Atlas/Build For Folder")]
static void BuildForSelectedFolder()
{
string assetPath = AssetDatabase.GetAssetPath(Selection.activeObject);
BuildForFolder(assetPath);
}
[MenuItem("Assets/Build Atlas/Build For Folder", true)]
static bool ValidateBuildForSelectedFolder()
{
string assetPath = AssetDatabase.GetAssetPath(Selection.activeObject);
string[] tempList = assetPath.Split('/');
if(assetPath.Contains(spriteFolder) &&
tempList.Length > 1)
{
return true;
}
return false;
}
private static void BuildForFolder(string assetPath)
{
//将路径切割
string[] tempList = assetPath.Split('/');
string atlasName = tempList[tempList.Length - 1];
string spritePath = Path.Combine(Application.dataPath, assetPath.Replace("Assets/", ""));
string atlasPath = Path.Combine(Application.dataPath, atlasFolder.Replace("Assets/", ""));
int size = 1024;
Process process = new Process();
ProcessStartInfo psi = new ProcessStartInfo();
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.RedirectStandardInput = true;
#if UNITY_EDITOR_OSX
psi.FileName = "/bin/sh";
psi.WorkingDirectory = Path.Combine(Application.dataPath, "../../Tools/TexturePacker/mac/TexturePacker.app/Contents/MacOS");
psi.Arguments = Path.Combine(Application.dataPath, "Editor/SpriteEditor/PackTexture.sh")
+ " " + atlasName
+ " " + spritePath
+ " " + atlasPath
+ " " + size;
#elif UNITY_STANDALONE_WIN
psi.FileName = "PackTexture.bat";
psi.WorkingDirectory = Path.Combine(Application.dataPath, "../../Tools/TexturePacker/wins/bin");
psi.Arguments = Path.Combine(Application.dataPath, "Editor/SpriteEditor/PackTexture.bat")
+ " " + atlasName
+ " " + spritePath
+ " " + atlasPath
+ " " + size;
#endif
process.StartInfo = psi;
try
{
if (process.Start())
{
string strOutput = process.StandardOutput.ReadToEnd();
string errorInfo = process.StandardError.ReadToEnd();
process.WaitForExit();
process.Close();
if (!string.IsNullOrEmpty(strOutput)) {
Debug.Log("Console outPut: " + strOutput);
}
if (!string.IsNullOrEmpty(errorInfo))
{
Debug.LogError("Console errorInfo: " + errorInfo);
}
}
}
catch (Exception e)
{
process.Close();
UnityEngine.Debug.LogError("========Fail to batch " + atlasName + ":" +e.ToString());
return;
}
AssetDatabase.Refresh();
SplitAtlasSprites(atlasName);
}
static void SplitAtlasSprites(string atlasName)
{
for (int i = 0; ; i++)
{
string texturePath = Path.Combine(atlasFolder, atlasName + "_" + i + ".png");
string textureFullPath = Path.Combine(Application.dataPath, texturePath.Replace("Assets/", ""));
if (!File.Exists(textureFullPath))
{
break;
}
TextureImporter ti = AssetImporter.GetAtPath(texturePath) as TextureImporter;
ti.textureType = TextureImporterType.Sprite;
ti.spriteImportMode = SpriteImportMode.Multiple;
ti.mipmapEnabled = false;
TextureImporterSettings tis = new TextureImporterSettings();
ti.ReadTextureSettings(tis);
tis.spriteMeshType = SpriteMeshType.Tight;
tis.spriteExtrude = 0;
//tis.alphaSource = TextureImporterAlphaSource.None;
ti.SetTextureSettings(tis);
string jsonPath = Path.Combine(atlasFolder, atlasName + "_" + i + ".txt");
string jsonFullPath = Path.Combine(Application.dataPath, jsonPath.Replace("Assets/", ""));
string configJson = File.ReadAllText(jsonFullPath, Encoding.UTF8);
JsonData configJsonData = JsonMapper.ToObject(configJson);
int textureHeight = int.Parse(configJsonData["meta"]["size"]["h"].ToString());
JsonData tempJsonData = configJsonData["frames"];
List<SpriteMetaData> metas = new List<SpriteMetaData>();
foreach (string name in tempJsonData.Keys)
{
JsonData frameData = tempJsonData[name]["frame"];
int x = int.Parse(frameData["x"].ToString());
int y = int.Parse(frameData["y"].ToString());
int w = int.Parse(frameData["w"].ToString());
int h = int.Parse(frameData["h"].ToString());
SpriteMetaData meta = new SpriteMetaData();
string subSpritePath = string.Format("Assets/AssetBundleData/UI/{0}/{1}.png", atlasName, name);
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(subSpritePath);
if (sprite != null && sprite.border != null)
{
UnityEngine.Debug.Log(sprite.border);
// meta.border = new Vector4(sprite.border.x, sprite.border.y, sprite.border.w, sprite.border.z);
meta.border = sprite.border;
}
meta.pivot = new Vector2(0.5f, 0.5f);
meta.alignment = (int)SpriteAlignment.Center;
meta.rect = new Rect(x, textureHeight - y - h, w, h);
meta.name = name;
metas.Add(meta);
}
ti.spritesheet = metas.ToArray();
ti.SaveAndReimport();
AssetDatabase.DeleteAsset(jsonPath);
//AssetDatabase.Refresh();
}
//AssetDatabase.Refresh();
}
}
为了防止误操作,这里对可打图集的资源目录做了限制
[MenuItem("Assets/Build Atlas/Build For Folder", true)]
static bool ValidateBuildForSelectedFolder()
{
string assetPath = AssetDatabase.GetAssetPath(Selection.activeObject);
string[] tempList = assetPath.Split('/');
if(assetPath.Contains(spriteFolder) &&
tempList.Length > 1)
{
return true;
}
return false;
}