在项目开发过程中我们必不可少的会将美术给的资源打包成图集来降低drawcall,减少包内存。

为了方便的生成图集,以及生成图片路径配置来方便通过图片名称快速定位所在的图集以及图片位置。

怎样实现一键导出图集扩展工具?

  1. 在工程目录设置一个存放UI图片资源的root目录
  2. 想要打包成同一图集的图片资源放在该目录下的同一文件夹下
  3. 创建 SpriteAtlasUtils 扩展编辑器脚本

代码实现思路

  1. 检查是否存在同名图片
  2. 生成 sprite 信息数据字典(名称,图集名,图集路径,图片路径)
  3. 通过 sprite 信息数据生成图集
  4. 生成 SpriteConfig 配置信息(用来通过图片名称查找所在图集路径|图片路径)

先看效果

关键代码:

  1. 获取root文件夹下的所有文件夹
  2. 获取某个文件夹下的所有图片资源guid(资源唯一标识)
  3. 通过唯一标识获取资源路径
     // 获取图片资源root下的所有文件夹string[] allPath = Directory.GetDirectories(SpriteRootPath);// 筛选出是sprite图片string[] guids = AssetDatabase.FindAssets("t:Sprite",new []{allPath[i]});// guid 转成资源路径string spritePath = AssetDatabase.GUIDToAssetPath(guids[j]);// 加载sprite资源Sprite sp = AssetDatabase.LoadAssetAtPath<Sprite>(spritePath);

创建图集

 // 创建图集SpriteAtlas atlas = new SpriteAtlas();// 添加图集所有图片atlas.Add(sprite);// 创建图集资源AssetDatabase.CreateAsset(atlas,path);

由于项目使用的是lua热更新所已导出的SpriteConfig是lua脚本,导出文件的难度也不大,废话不多说,直接看下面完整代码吧

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEditor.U2D;
using UnityEngine;
using UnityEngine.U2D;namespace Editor.UI.Atlas
{public static class SpriteAtlasUtils{public class SpriteData{public string name;public string path;public string atlasName;public Sprite sprite;}private const string SpriteRootPath = "Assets/UI/Sprite/";private const string SpriteAtlasRootPath = "Assets/UI/Atlas";private const string SpriteConfigPath = "Assets/Scripts/Lua/Configs/SpriteConfig.lua";private const stringSpriteConfigTemplate = "Assets/Scripts/CS/Core/UI/LuaTemplate/SpriteConfigTemplate.txt"; // 模板文件[MenuItem("My菜单/导出图集")]private static void Execute(){float total = 5;float temp = 0;ShowProgress("检查是否重名", ++temp, total);if (CheckTheSameName()){EditorUtility.ClearProgressBar();return;}ShowProgress("生成图集数据", ++temp, total);Dictionary<string, List<SpriteData>> spriteDic = GenerateSpriteData();ShowProgress("生成图集", ++temp, total);GenerateSpriteAtlas(spriteDic);ShowProgress("生成配置数据", ++temp, total);GenerateSpriteConfig(spriteDic);ShowProgress("生成图集结束", ++temp, total);EditorUtility.DisplayDialog("导出图集", $"图集导出成功,总共导出 {spriteDic.Count} 张图集", "OK");EditorUtility.ClearProgressBar();}[MenuItem("My菜单/清空图集")]private static void Clear(){var guids = AssetDatabase.FindAssets("", new[] {SpriteAtlasRootPath});for (int i = 0; i < guids.Length; i++){AssetDatabase.DeleteAsset(AssetDatabase.GUIDToAssetPath(guids[i]));}AssetDatabase.Refresh();}// 生成图集数据private static Dictionary<string,List<SpriteData>> GenerateSpriteData(){// 获取图片资源root下的所有文件夹string[] allPath = Directory.GetDirectories(SpriteRootPath);Dictionary<string,List<SpriteData>> atlasDic = new Dictionary<string, List<SpriteData>>();for (int i = 0; i < allPath.Length; i++){string atlasName = Path.GetFileNameWithoutExtension(allPath[i]);// 筛选出是sprite图片string[] guids = AssetDatabase.FindAssets("t:Sprite",new []{allPath[i]});List<SpriteData> spriteDatas = new List<SpriteData>();for (int j = 0; j < guids.Length; j++){// guid 转成资源路径string spritePath = AssetDatabase.GUIDToAssetPath(guids[j]);// 加载sprite资源Sprite sp = AssetDatabase.LoadAssetAtPath<Sprite>(spritePath);SpriteData data = new SpriteData();data.name = Path.GetFileNameWithoutExtension(spritePath);data.path = spritePath;data.sprite = sp;data.atlasName = atlasName;spriteDatas.Add(data);}atlasDic.Add(atlasName,spriteDatas);}return atlasDic;}// 生成图集private static void GenerateSpriteAtlas(Dictionary<string,List<SpriteData>> spriteDic){foreach (var datas in spriteDic){// 创建图集SpriteAtlas atlas = new SpriteAtlas();// 添加图集所有图片atlas.Add(datas.Value.Select(t=> t.sprite).ToArray());string path = SpriteAtlasRootPath + "/" + datas.Key + ".spriteatlas";if (!Directory.Exists(SpriteAtlasRootPath)){Directory.CreateDirectory(SpriteAtlasRootPath);}// 创建图集资源AssetDatabase.CreateAsset(atlas,path);}// 刷新文件AssetDatabase.Refresh();}// 检查是否重名private static bool CheckTheSameName(){Dictionary<string, List<string>> pathDic = new Dictionary<string, List<string>>();List<string> theSameKeys = new List<string>();// 获取所有图片文件夹string[] allPath = Directory.GetDirectories(SpriteRootPath);for (int i = 0; i < allPath.Length; i++){// 获取文件夹下的所有资源唯一标识idstring[] guids = AssetDatabase.FindAssets("t:Sprite",new []{allPath[i]});for (int j = 0; j < guids.Length; j++){// 通过资源guid获得资源路径string spritePath = AssetDatabase.GUIDToAssetPath(guids[j]);string spName = Path.GetFileNameWithoutExtension(spritePath);List<string> pathList = null;if (pathDic.TryGetValue(spName,out pathList)){if (!theSameKeys.Contains(spName)){theSameKeys.Add(spName);}}else{pathList = new List<string>();pathDic.Add(spName,pathList);}pathList.Add(spritePath);}}if (theSameKeys.Count > 0){string msg = "";for (int i = 0; i < theSameKeys.Count; i++){List<string> pList = pathDic[theSameKeys[i]];for (int j = 0; j < pList.Count; j++){msg = msg + pList[j] + "\n";}}if (EditorUtility.DisplayDialog("出现同名sprite", msg, "确定")){}return true;}return false;}// 生成配置private static void GenerateSpriteConfig(Dictionary<string, List<SpriteData>> spriteDic){StreamReader streamReader = File.OpenText(SpriteConfigTemplate);string template = streamReader.ReadToEnd();streamReader.Close();StreamWriter streamWriter = File.CreateText(SpriteConfigPath);StringBuilder atlasPathStr = new StringBuilder();StringBuilder spritePathStr = new StringBuilder();StringBuilder spriteAtlasPathStr = new StringBuilder();foreach (var info in spriteDic){string atlasName = info.Key;string atlasPath = SpriteAtlasRootPath + atlasName;atlasPathStr.AppendLine(string.Format("\t{0} = '{1}';", atlasName,atlasPath));for (int i = 0; i < info.Value.Count; i++){spritePathStr.AppendLine(string.Format("\t['{0}'] = '{1}';",info.Value[i].name ,info.Value[i].path));spriteAtlasPathStr.AppendLine(string.Format("\t['{0}'] = {1};",info.Value[i].name,"M.AtlasPath." + atlasName));}}template = template.Replace("$ATLASPATH$", atlasPathStr.ToString()).Replace("$SPRITEPATH$", spritePathStr.ToString()).Replace("$SPRITEATLASPATH$", spriteAtlasPathStr.ToString());streamWriter.WriteLine(template);streamWriter.Close();}// 显示进度private static void ShowProgress(string info,float tmp,float total){EditorUtility.DisplayProgressBar("生成图集", info, tmp / total);}}
}

Unity拓展编辑器 一键导出图集工具相关推荐

  1. Unity 拓展编辑器 - 导出UI预制体lua文件

    使用oldin插件 + Unity自带拓展编辑器编写 实现效果: 界面配置基类:UIDialogConfig using Sirenix.OdinInspector; using UnityEngin ...

  2. Unity编辑器扩展: 程序化打图集工具

    开始前的声明:该案例中图集所使用图片资源均来源于网络,仅限于学习使用 一.前言 关于编辑器扩展相关的知识,在前面的两篇内容中做了详细的描述,链接地址: 第一篇 :Unity编辑器扩展 UI控件篇 第二 ...

  3. Unity 工具 之 图集根据切割为一张张单张图片的简单封装(Unity 自带 SpritePackage 打包图集的性能优化)

    Unity 工具 之 图集根据切割为一张张单张图片的简单封装(Unity 自带 SpritePackage 打包图集的性能优化) 目录 一.简单介绍 二.实现原理 三.注意事项 四.实现步骤 五.关键 ...

  4. 一键导出/备份「有道云笔记」工具

    今天给大家推荐一个有道云笔记的导出备份工具.我虽然是有道云笔记的用户,但是作为程序员还是希望笔记能够再备份一份,同时后续如果有更换其他笔记工具的计划,可以做到无缝切换. 之所以会有这个工具,是因为官方 ...

  5. Unity批量替换文字字体自制工具

    本工具就如标题一样,是用来批量替换unity中Text组件中的字体的工具. 原理就是查找文件夹下的所有预制体,批量修改预制体中存在的Text组件的字体数据.有做一个指定某种字体替换到另外一种字体的功能 ...

  6. 知乎回答一键导出为PDF——Python实现

    文章目录 为什么做知乎回答的导出? 实现环境 源代码 PDF导出测试结果 为什么做知乎回答的导出? "恰同学少年,风华正茂: 书生意气,挥斥方遒. 指点江山,激扬文字-" 知乎上总 ...

  7. 学术党必备:Zotero一键导出BibTex 参考文献

    如果你没用过Zotero,那我强烈安利你用一下. 推荐一个软件:论文翻译阅读 + 文献管理 + markdown笔记 + 多设备同步 + 一键导出bib参考文献 文章目录 1. 使用zotero一键导 ...

  8. Android NDK 导出独立工具链

    传统方式调试 NDK 开发的程序比较麻烦,先要编译成 JNI,又要导出 java接口,还要再写一个 java 工程,改一个地方又要连续改几处,这样效率是很低的.最频繁使用的关键工作路径(编译/调试环节 ...

  9. 包画三维散点图怎么导出_不开玩笑,发现宝藏了,一键导出场地三维模型,连贴图都有!...

    --文末获取,城市模型下载中文工具+中文学习教程-- Esri CityEngine是三维城市建模的首选软件,应用于数字城市.城市规划.轨道交通.电力.管线.建筑.国防.仿真.游戏开发和电影制作等领域 ...

  10. 12.一键导出微信读书的书籍和笔记

    # 一键导出微信读书的书籍和笔记> 本项目基于[@arry-lee](https://github.com/arry-lee)的项目[wereader](https://github.com/a ...

最新文章

  1. IO-3(Reader、Writer、编码、FileReader、FileWriter)
  2. df命令,du命令,磁盘分区
  3. 解决Apache/PHP无法启动的问题
  4. Pandownload百度网盘不限速下载器PC版|Android版
  5. vue 实现图片预览
  6. OV5640_MIPI_1LEN调试记录
  7. 计算机键盘符号称呼,电脑键盘上特殊符号和标点符号名称的输入方法汇总
  8. 『单片机原理』程序存储器的结构
  9. CSS弹性盒子布局flex
  10. python画动画爱心
  11. uniApp入门(一)
  12. OneDrive教育版注册和登录
  13. 数据模拟:利用Java模拟数据(姓名,邮箱,地址,电话等信息,时间,工资,1-10随机数)并存入mysql
  14. EfficientPS网络
  15. confluence 使用教程
  16. 服务器响应程序,封装高可复用的服务端响应SSC程序修复对象 --ServerResponse
  17. 我来回答,害怕别人赚钱到底是一种什么样的心理
  18. 1003: 两个整数的四则运算 C语言
  19. LabVIEW使用G#框架实现面向对象编程
  20. 【UE4】纯蓝图实现数据表(DataTable)的写入存储

热门文章

  1. ThinkPHP视频教程 PHP-ThinkPHP 8天课程完整版
  2. c语言程序设计教程pdf下载,C语言程序设计教程PDF合集-中国科技大学.pdf
  3. 远程显示协议对比:RemoteFX vs. HDX vs. PCoIP
  4. html5swf小游戏源码,FLASH打方块小游戏及as3代码
  5. android源码学习-源码学习目录推荐
  6. java实验报告的原理_JAVA实验报告
  7. oracle 11g sql和pl/sql从入门到精通,Oracle 11g SQL和PL SQL从入门到精通_IT教程网
  8. MATLAB秦九韶算法
  9. GJB 150.10军用设备环境试验方法霉菌试验
  10. html视频直播源码,用HTML5开发简单的视频播放器,附源码