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 = ;//最大图集尺寸
static float padding = ;//每两个图片之间用多少像素来隔开
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 = ; 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 <= )
{
Debug.Log("请先选择要合并的小图或小图的目录");
return;
} for (var i = ; 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 = ; 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 = ; 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(, );
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 = ; 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 - )
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 = ; i < spriteList.Count; i++)
{
if (spriteList[i].name == texName)
{
return spriteList[i];
}
}
//Debug.Log("Can not find texture metadata : " + texName);
return null;
} }
UGUI打图集
UGUI 打图集的更多相关文章
- Unity 利用UGUI打包图集,动态加载sprite资源
今天做了一个UI界面,这个界面是好友界面,该界面上有若干个好友item. 需要对每个tem的头像对象(image)动态显示对应的头像.尝试利用UGUI的图集来加载,具体实现如下: 1.首先,需要知道S ...
- UGUI的图集处理方式-SpriteAtlas的前世今生
最糟糕的是人们在生活中经常受到错误志向的阻碍而不自知,真到摆脱了那些阻碍时才能明白过来. —— 歌德 说到UGUI的图集初学者可能觉得没什么难度,包括我刚开始接触的时候也是,甚至你在开发的时候只需要把 ...
- 转:UGUI与NGUI的区别与优缺点
1. NGUI与UGUI的区别 1) uGUI的Canvas 有世界坐标和屏幕坐标 2) uGUI的Image可以使用material 3) UGUI通过Mask来裁剪,而NGUI通过Pa ...
- [置顶]
Unity2d引入新功能SpriteAtlas,Sprite新的图集方式
孙广东 2017.8.3 http://blog.csdn.NET/u010019717 在Unity 2017.1.0f3中引入了 SpriteAtlas 官方文档: https://docs. ...
- (转)Unity 之 UGUI 小总结
转自:http://www.jianshu.com/p/5b6f5022662e 开发过程中对UGUI的一个小总结. 首先从原画师拿到效果图,美术切图,拿到碎图后打成大图. 我们先来说一下图:RGBA ...
- 关于Unity中的UGUI优化,你可能遇到这些问题
https://blog.uwa4d.com/archives/QA_UGUI-1.html 关于Unity中的UGUI优化,你可能遇到这些问题 作者:admin / 时间:2016年11月08日 / ...
- NGUI_概述
序言:这是张三疯第一次开始NGUI插件的学习,刚开始学习,肯定有很多漏洞,后期会及时的补上的. 希望大家可以见谅,希望大佬多多指教. 一.什么是NGUI: NGUI是严格遵循KISS原则并用C#编写的 ...
- U3D面试题
直接上新.... 什么是协同程序?答:在主线程运行时同时开启另一段逻辑处理,来协助当前程序的执行.换句话说,开启协程就是开启一个可以与程序并行的逻辑.可以用来控制运动.序列以及对象的行为. Unity ...
- Unity -----一些可能存在的错误
关于Unity中的资源管理,你可能遇到这些问题 张鑫 8 个月前 原文链接:关于Unity中的资源管理,你可能遇到这些问题 - Blog 在优化Unity项目时,对资源的管理可谓是个系统纷繁的大工程. ...
随机推荐
- SCSS快速入门
SCSS快速入门 1. 使用变量sass引入了变量.通过变量名来引用它们,使用$符号来标识变量.且在CSS中并无他用,不会导致与现存或未来的css语法冲突. 1-1. 变量声明sass变量的声明和cs ...
- 一个1级分组基础上同时进行2级分组的SQL面试题
示例1:测试数据: SQL> select * from score; ID CLASS STUDENT COURSE SCORE ---------- ----- ------- - ...
- iOS引用类型
强引用, 默认引用类型.被强引用指向的内存不被释放.强引用会对被引用对象的引用计数器+1,从而扩展对象的生命周期. 弱引用, 弱引用是医用特殊的引用类型.它不会增加引用计数器,因而不会扩展对象的生命周 ...
- 查找->静态查找表->顺序查找(顺序表)
文字描述 顺序查找的查找过程为:从表中最后一个记录开始,逐个进行记录的关键字和给定值的比较,若某个记录的关键字和给定值比较相等,则查找成功,找到所查记录:反之,若直至第一个记录,其关键字和给定值比较都 ...
- fiddler4如何只抓取指定浏览器的包
在实际工作中,常常会抓取浏览器的数据,其加载的数据较多,不好区分,不知道其是哪个是需要抓取的数据,所以就需抓取指定浏览器的数据,这样就能很清晰知道数据的来源. 步骤一: 打开fiddler4,再打开浏 ...
- 创建日志表记录DML操作和DDL操作
创建一个日志表,记录dept表的DML操作 create table dept_log(logid number,type varchar2(50),logdate date,deptno numbe ...
- pandas基础
1.相关库导入 2.创建数据结构 pandas 有两个重要的数据结构: Series 和 DataFrame 创建Series数组,代表一行或一列 创建DataFrame ,代表二维数组 第一种方式: ...
- 10.8-uC/OS-III内部任务(中断处理任务 OS_IntQTask())
1.当设置OS_CFG.H中的OS_CFG_ISR_POST_DEFERRED_EN为1时, uC/OS-III就会创建一个任务,它的作用是尽快完成ISR中对post函数的调用, 将信号量.消息等对象 ...
- WebSocket 学习教程(一):理论
一.WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通 ...
- Laravel项目October安装
October是一个免费,开源,自托管的基于laravel PHP框架CMS平台.在github平台上laravel应用排名第二,可以拿来研究一下.官方介绍:October是一个内容管理系统(CMS) ...