这一节我们来写一下怎么用代码吧很多图片打到一个图集中(也就是一个大图片中)

在Unity中我们可以设置图片的Packing Tag来制定图片所属的图集,Unity运行的时候会把相同图集的图片合批,我们自己来实现一个这样的功能.

假如我们有下面这些图片

打成图集之后的效果如下

然后我们就可以像这样来使用

Sprite[] sprite = Resources.LoadAll<Sprite>(path);
image.sprite = sprite[1];

具体使用方式如下

下面是完整的代码,基本每一行都有注释

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;//是否开启mipmapimp.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;}}

Unity 打图集Atlas相关推荐

  1. Unity shader图集Atlas下的UV坐标归一化转换

    unity中如果图片打入了图集中,在shader中取到的uv坐标默认是图集中的坐标,如果需要shader做一些类似流光的效果,需要转换成常用的0-1区间的归一化uv坐标,转换方法如下: 步骤一: C# ...

  2. Unity UGUI图集专题

    一:图集介绍 什么是图集:我们可以将其理解为将一系列小图合并为一张大图.使用图集可以减少drawcall,提升效率. ​ 游戏中的图片模型最终是要给到显卡去渲染的,然后CPU通知GPU要开始渲染,这一 ...

  3. Unity 打包图集

    Unity打包图集 public class MyTexturePak {private const string intPutPath = "/Emoji/Input/";pri ...

  4. Unity一键图集生成工具,附源码 (基于NGUI和TexturePacker)

    https://blog.uwa4d.com/archives/NGUI_SplitChannels.html Unity一键图集生成工具,附源码 (基于NGUI和TexturePacker) 作者: ...

  5. 【Sprite Atlas】Unity新图集系统SpriteAtlas超详细使用教程

    SpriteAtlas是Unity新出的一个功能,用来取代旧版的Sprite Packer. 图集打包的意义: 减少DrawCall 图集将图片打包为2的幂次方的素材大小,可以提升性能 减小包体大小 ...

  6. 2022-04-24 Unity UGUI5——图集

    文章目录 一.Drawcall 二.图集 一.Drawcall ​ 字面理解 DrawCall,就是绘制呼叫的意思,表示 CPU(中央处理器)通知 GPU(图形处理器-显卡) (一)DrawCall ...

  7. sprite的大小 unity_[Unity]SpriteShape与atlas的小坑

    现象 今天打Android包发现场景中有几处2D地形显示不正常,查看后发现是此处用了SpriteShape做了可编辑的地形.然后在Editor模式里用bundle模式跑了一下,发现在SpriteSha ...

  8. 【Unity】Sprite Atlas功能讲解

    目录 SpriteAtlas创建方法 1.Type: Maskter母版 Variant变体 2.Include Build: 勾选时运行游戏时自动加载入内存中,否则需要手动加载(使用到的时候才会加载 ...

  9. unity 动态图集

    不管NGUI还是UGUI,图集都是在制作期间就生成了的,运行时是一张大图,这样做的好处在于我们可以在一定程度上去合并批次,但是图集通常在制作过程中,会分成commonatlas和系统atlas两类,一 ...

  10. Unity替换 图集

    替换图集 两个图集中有大量同名资源要替换 两个图集中有大量同名资源要替换 using System.Collections; using System.Collections.Generic; usi ...

最新文章

  1. 2021年大数据Flink(四十):​​​​​​​Flink模拟双十一实时大屏统计
  2. 一步一步学lucene——(第四步:搜索篇)
  3. 全球及中国汽车轮胎再制造市场销售产值与运营发展模式分析报告2022年
  4. 何为奇偶校验码?简述它们的区别。_加速试验中,HAST和HASS的区别
  5. SAP Spartacus 服务器端渲染单步调试步骤之二:在服务器端执行应用程序 Angular 代码
  6. HTML常用meta大全
  7. c语言fseek128字节,C语言rewind和fseek函数的用法详解(随机读写文件)
  8. 转载 敏捷教练,从A到Z
  9. oracle查询:分组查询,取出每组中的第一条记录
  10. qt分割获取文件路径(去文件名)
  11. React antD 使用Select 进阶功能 远程搜索,防抖控制,加载状态
  12. Genymotion启动报错:VT-x/AMD-V硬件加速在您的系统中不可用
  13. php遍历文件夹下文件内容_PHP遍历文件夹下所有文件和文件夹
  14. python爬虫--看看虎牙女主播中谁最“顶”
  15. HM-A300小程序安卓打印异常
  16. 47页数字孪生人脸识别轨迹分析电子围栏智慧工地解决方案
  17. 求解会议安排问题 C++实现
  18. 大疆livox定制的格式CustomMsg格式转换pointcloud2
  19. 高仿富途牛牛-组件化-界面美化
  20. 大二下学期ACM比赛总结

热门文章

  1. iOS最新面试题(一)
  2. STM32F103X hal RTThread rtc驱动支持日期保存
  3. python实现对图片的一些简单处理
  4. python自测单词软件_还在用背单词App?使用Python开发英语单词自测工具,助你逆袭单词王!...
  5. Elasticsearch 安装详细步骤(保姆级安装)
  6. python语义分析_Python - Sentiment Analysis
  7. 能力培养——学会学习
  8. 密码分析之单表代换原理详解与算法实现
  9. python3+selenium3+IE自动化遇IE11下载弹窗遇阻
  10. Mathtype 花体字 Euclid math one/two 不能显示的问题