首页 > 编程知识 正文

unity 基于FGUI编辑器导出的集切工具

时间:2023-05-03 12:24:38 阅读:279589 作者:2457

最近项目优化需要打图集,由于Unity的SpritePacker没用过,TexturePacker不会用,上个项目用的又是FariyGUI自己比较熟悉,导出的直接就是打好的图集特别好用,当然导出的图集是给FGUI自己使用,我们项目用的时UGUI,所以还需要对图集做下处理。

废话不多说我们直接上图,首先在FGUI的编辑器中创建一个空包,包名就是图片的名字,因为我们只是打图集,所以里面组件删掉不留任何东西。

把准备好的图片导入进来

发布设置需要注意:包格式不要使用二进制格式,以及纹理集取消分离Alpha通道。

还有不能分页,如果需要打的图片过多超出了2048X2048,可以自己手动打两次。

然后记得选中图片设置导出,发布。

发布成功后我们会得到三个文件

然后开始写编辑器脚本:

using System.Collections.Generic;using System.IO;using System.Reflection;using System.Text.RegularExpressions;using UnityEditor;using UnityEngine;using UnityEngine.Events;public class FariyGUICuttingAtlas : AssetPostprocessor{ string fguiTextureId = "@atlas0.png"; string fguiByteId = "@sprites.bytes"; string fguiByteToId = ".bytes"; string regexStr = "<image id="(?<key1>.*?)" name="(?<key2>.*?)" path"; //匹配字符串值 string regexStrTo = @"^(?=.*id=)(?=.*name=).*$"; //检查字符串是否匹配 UnityAction action; public void OnPreprocessTexture() { //Debug.Log(texture.texelSize.y); //导入图片文件名(有扩展名) string name = Path.GetFileName(assetImporter.assetPath); //文件名校验 if (name.Contains(fguiTextureId)) { //导入路径(纯路径,无文件名) string path = assetImporter.assetPath.Replace(name, ""); //导入图片文件名(去除扩展名,去除标志符) string spriteName = name.Replace(fguiTextureId, ""); //图集信息文件路径 string bytesSpritesPath = path + spriteName + fguiByteId; //图集名字信息对应文件路径 string bytesPath = path + spriteName + fguiByteToId; //校验图集信息文件是否存在 if (File.Exists(bytesSpritesPath) && File.Exists(bytesPath)) { StartCuttingAtlas(ReadBytesFile(bytesSpritesPath), ReadBytesToFile(bytesPath)); LastOperation(path, bytesSpritesPath, bytesPath); if (File.Exists(assetImporter.assetPath)) { EditorApplication.update += EditorUpdate; action = new UnityAction(() => { AssetDatabase.RenameAsset(path + name, spriteName + ".png"); }); } } } } float totalTime = 0; public void EditorUpdate() { if (totalTime>=1) { totalTime = 0; if (action!=null) { action(); action = null; } EditorApplication.update -= EditorUpdate; } else totalTime = totalTime + Time.deltaTime; } void LastOperation(string spritePath, string bytesSpritesPath, string bytesPath) { FileUtil.DeleteFileOrDirectory(bytesPath); FileUtil.DeleteFileOrDirectory(bytesSpritesPath); } List<string> ReadBytesFile(string path) { StreamReader sr = new StreamReader(path, System.Text.Encoding.Default); List<string> list = new List<string>(); string line; while ((line = sr.ReadLine()) != null) { if (line.Substring(0, 2) != "//") list.Add(line); } sr.Close(); return list; } Dictionary<string, string> ReadBytesToFile(string path) { StreamReader sr = new StreamReader(path, System.Text.Encoding.Default); Dictionary<string, string> dic = new Dictionary<string, string>(); string line; while ((line = sr.ReadLine()) != null) { Regex reg = new Regex(regexStr); Match match = reg.Match(line); if (Regex.IsMatch(line, regexStrTo)) { if (match.Success) dic.Add(match.Groups["key1"].Value, match.Groups["key2"].Value); } } sr.Close(); return dic; } Dictionary<string, int[]> dictionart; string[] sArray; string key; int[] value; void StartCuttingAtlas(List<string> list, Dictionary<string, string> listTo) { dictionart = new Dictionary<string, int[]>(); for (int i = 0; i < list.Count; i++) { sArray = list[i].Split(' '); if (sArray.Length == 11 && listTo.ContainsKey(sArray[0])) { key = listTo[sArray[0]]; value = new int[sArray.Length - 1]; for (int n = 1; n < sArray.Length; n++) { value[n - 1] = int.Parse(sArray[n]); } dictionart.Add(key, value); CuttingAtlas(dictionart); } else Debug.Log("数据表中没有相对应的图片名!"); } } TextureImporter texImpoter; SpriteMetaData[] spriteDataArray; object[] args; void CuttingAtlas(Dictionary<string, int[]> dictionart) { texImpoter = assetImporter as TextureImporter; texImpoter.textureType = TextureImporterType.Sprite; texImpoter.isReadable = true; texImpoter.spriteImportMode = SpriteImportMode.Multiple; spriteDataArray = new SpriteMetaData[dictionart.Count]; int i = 0; args = new object[2]; MethodInfo info = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance); info.Invoke(texImpoter, args); int maxHenght = (int)args[1]; foreach (KeyValuePair<string,int[]> item in dictionart) { spriteDataArray[i] = SetSpriteSheet(item.Key,item.Value, maxHenght); i++; } texImpoter.spritesheet = spriteDataArray; } SpriteMetaData spriteData; SpriteMetaData SetSpriteSheet(string name,int[] table,int maxHenght) { spriteData = new SpriteMetaData(); spriteData.name = name; int y = maxHenght - table[4]; spriteData.rect = new Rect(table[1], y- table[2], table[3], table[4]); return spriteData; }

脚本写好后放到Editor文件夹下,然后把FGUI导出的三个文件拖进来,图集就自动切好了。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。