UGUI打图集
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;
using System.IO;
using System.Text;public class AtlasCreate
{
//用來保存圖片中的設置信息 比如用RGBA32壓縮格式等
public class TextureImporterSettings
{
public bool isReadable;//紋理信息在內存中是否可讀
public TextureImporterFormat textureFormat;//紋理的格式public TextureImporterSettings(bool isReadable, TextureImporterFormat textureFormat)
{
this.isReadable = isReadable;
this.textureFormat = textureFormat;
}
}
//用來保存單個圖片的信息
public class SpriteInfo
{
public string name;//圖片的名字
public Vector4 spriteBorder;//圖片的包圍盒(如果有的話)
public Vector2 spritePivot;//圖片包圍盒中的中心軸(如果有的話)
public float width;
public float height;public SpriteInfo(string name, Vector4 border, Vector2 pivot, float w, float h)
{
this.name = name;
spriteBorder = border;
spritePivot = pivot;
width = w;
height = h;
}
}
static float matAtlasSize = 2048;//最大圖集尺寸
static float padding = 1;//每兩個圖片之間用多少像素來隔開
private static List<SpriteInfo> spriteList = new List<SpriteInfo>();
[MenuItem("Assets/AtlasCreate")]
static public void Init()
{
string assetPath;
//根據我們的選擇來獲取選中物體的信息
Object[] objs = Selection.GetFiltered(typeof(Texture), SelectionMode.DeepAssets);
//判斷圖片命名的合法性
for (int i = 0; i < objs.Length; i++)
{
Object obj = objs[i];
if (obj.name.StartsWith(" ") || obj.name.EndsWith(" "))
{
string newName = obj.name.TrimStart(' ').TrimEnd(' ');
Debug.Log(string.Format("rename texture'name old name : {0}, new name {1}", obj.name, newName));
AssetDatabase.RenameAsset(AssetDatabase.GetAssetPath(obj), newName);
}
}
Texture2D[] texs = new Texture2D[objs.Length];//用來保存objs中的物體
if (texs.Length <= 0)
{
Debug.Log("請先選擇要合并的小圖或小圖的目錄");
return;
}for (var i = 0; i < objs.Length; i++)
{
texs[i] = objs[i] as Texture2D;
assetPath = AssetDatabase.GetAssetPath(texs[i]);
AssetDatabase.ImportAsset(assetPath);//重新把圖片導入內存,理論上unity工程中的資源在用到的時候,Unity會自動導入到內存,但有的時候卻沒有自動導入,為了以防萬一,我們手動導入一次
}//得到圖片的設置信息
TextureImporterSettings[] originalSets = GatherSettings(texs);//根據我們的需求 設置圖片的一些信息.
for (int i = 0; i < texs.Length; i++)
{
SetupTexture(texs[i], true, TextureImporterFormat.RGBA32);
}
//最終打成的圖集路徑,包括名字
assetPath = "Assets/Atlas.png";
string outputPath = Application.dataPath + "/../" + assetPath;
//主要的打圖集代碼
PackAndOutputSprites(texs, assetPath, outputPath);
//打出圖集后在Unity選中它
EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath(assetPath, typeof(Texture)));
}
//得到圖片的設置信息
static public TextureImporterSettings[] GatherSettings(Texture2D[] texs)
{
TextureImporterSettings[] sets = new TextureImporterSettings[texs.Length];
for (var i = 0; i < texs.Length; i++)
{
var tex = texs[i];
var assetPath = AssetDatabase.GetAssetPath(tex);
TextureImporter imp = AssetImporter.GetAtPath(assetPath) as TextureImporter;
sets[i] = new TextureImporterSettings(imp.isReadable, imp.textureFormat);
//如果圖片由包圍盒的話 記錄包圍盒信息
if (imp.textureType == TextureImporterType.Sprite && imp.spriteBorder != Vector4.zero)
{
var spriteInfo = new SpriteInfo(tex.name, imp.spriteBorder, imp.spritePivot, tex.width, tex.height);
spriteList.Add(spriteInfo);
}
}
return sets;
}
//根據我們的需求 設置圖片的一些信息.
static public void SetupTexture(Texture2D tex, bool isReadable, TextureImporterFormat textureFormat)
{
var assetPath = AssetDatabase.GetAssetPath(tex);
TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
importer.isReadable = isReadable;//圖片是否可讀取它的內存信息
importer.textureFormat = textureFormat;//圖片的格式
importer.mipmapEnabled = false;//是否生成mipmap文件
importer.npotScale = TextureImporterNPOTScale.None;//用于非二次冪紋理的縮放模式
importer.SaveAndReimport();//刷新圖片
}static public void PackAndOutputSprites(Texture2D[] texs, string atlasAssetPath, string outputPath)
{
Texture2D atlas = new Texture2D(1, 1);
Rect[] rs = atlas.PackTextures(texs, (int)padding, (int)matAtlasSize);//添加多個圖片到一個圖集中,返回值是每個圖片在圖集(大圖片)中的U坐標等信息
// 把圖集寫入到磁盤文件,最終在磁盤上會有一個圖片生成,這個圖片包含了很多小圖片
File.WriteAllBytes(outputPath, atlas.EncodeToPNG());
RefreshAsset(atlasAssetPath);//刷新圖片//記錄圖片的名字,只是用于輸出日志用;
StringBuilder names = new StringBuilder();
//SpriteMetaData結構可以讓我們編輯圖片的一些信息,想圖片的name,包圍盒border,在圖集中的區域rect等
SpriteMetaData[] sheet = new SpriteMetaData[rs.Length];
for (var i = 0; i < sheet.Length; i++)
{
SpriteMetaData meta = new SpriteMetaData();
meta.name = texs[i].name;
meta.rect = rs[i];//這里的rect記錄的是單個圖片在圖集中的uv坐標值
//因為rect最終需要記錄單個圖片在大圖片圖集中所在的區域rect,所以我們做如下的處理
meta.rect.Set(
meta.rect.x * atlas.width,
meta.rect.y * atlas.height,
meta.rect.width * atlas.width,
meta.rect.height * atlas.height
);
//如果圖片有包圍盒信息的話
var spriteInfo = GetSpriteMetaData(meta.name);
if (spriteInfo != null)
{
meta.border = spriteInfo.spriteBorder;
meta.pivot = spriteInfo.spritePivot;
}
sheet[i] = meta;
//打印日志用
names.Append(meta.name);
if (i < sheet.Length - 1)
names.Append(",");
}//設置圖集的信息
TextureImporter imp = TextureImporter.GetAtPath(atlasAssetPath) as TextureImporter;
imp.textureType = TextureImporterType.Sprite;//圖集的類型
imp.textureFormat = TextureImporterFormat.AutomaticCompressed;//圖集的格式
imp.spriteImportMode = SpriteImportMode.Multiple;//Multiple表示我們這個大圖片(圖集)中包含很多小圖片
imp.mipmapEnabled = false;//是否開啟mipmap
imp.spritesheet = sheet;//設置圖集中小圖片的信息(每個圖片所在的區域rect等)
// 保存并刷新
imp.SaveAndReimport();
spriteList.Clear();
//輸出日志
Debug.Log("Atlas create ok. " + names.ToString());
}
//刷新圖片
static public void RefreshAsset(string assetPath)
{
AssetDatabase.Refresh();
AssetDatabase.ImportAsset(assetPath);
}
//得到圖片的信息
static public SpriteInfo GetSpriteMetaData(string texName)
{
for (int i = 0; i < spriteList.Count; i++)
{
if (spriteList[i].name == texName)
{
return spriteList[i];
}
}
//Debug.Log("Can not find texture metadata : " + texName);
return null;
}}
總結
- 上一篇: 前后端发包操作
- 下一篇: 据我爱无人机网两家国外公司合作开展无人机