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 打图集的更多相关文章

  1. Unity 利用UGUI打包图集,动态加载sprite资源

    今天做了一个UI界面,这个界面是好友界面,该界面上有若干个好友item. 需要对每个tem的头像对象(image)动态显示对应的头像.尝试利用UGUI的图集来加载,具体实现如下: 1.首先,需要知道S ...

  2. UGUI的图集处理方式-SpriteAtlas的前世今生

    最糟糕的是人们在生活中经常受到错误志向的阻碍而不自知,真到摆脱了那些阻碍时才能明白过来. —— 歌德 说到UGUI的图集初学者可能觉得没什么难度,包括我刚开始接触的时候也是,甚至你在开发的时候只需要把 ...

  3. 转:UGUI与NGUI的区别与优缺点

    1. NGUI与UGUI的区别 1) uGUI的Canvas 有世界坐标和屏幕坐标   2) uGUI的Image可以使用material     3) UGUI通过Mask来裁剪,而NGUI通过Pa ...

  4. [置顶] Unity2d引入新功能SpriteAtlas,Sprite新的图集方式

    孙广东  2017.8.3 http://blog.csdn.NET/u010019717 在Unity 2017.1.0f3中引入了 SpriteAtlas 官方文档:  https://docs. ...

  5. (转)Unity 之 UGUI 小总结

    转自:http://www.jianshu.com/p/5b6f5022662e 开发过程中对UGUI的一个小总结. 首先从原画师拿到效果图,美术切图,拿到碎图后打成大图. 我们先来说一下图:RGBA ...

  6. 关于Unity中的UGUI优化,你可能遇到这些问题

    https://blog.uwa4d.com/archives/QA_UGUI-1.html 关于Unity中的UGUI优化,你可能遇到这些问题 作者:admin / 时间:2016年11月08日 / ...

  7. NGUI_概述

    序言:这是张三疯第一次开始NGUI插件的学习,刚开始学习,肯定有很多漏洞,后期会及时的补上的. 希望大家可以见谅,希望大佬多多指教. 一.什么是NGUI: NGUI是严格遵循KISS原则并用C#编写的 ...

  8. U3D面试题

    直接上新.... 什么是协同程序?答:在主线程运行时同时开启另一段逻辑处理,来协助当前程序的执行.换句话说,开启协程就是开启一个可以与程序并行的逻辑.可以用来控制运动.序列以及对象的行为. Unity ...

  9. Unity -----一些可能存在的错误

    关于Unity中的资源管理,你可能遇到这些问题 张鑫 8 个月前 原文链接:关于Unity中的资源管理,你可能遇到这些问题 - Blog 在优化Unity项目时,对资源的管理可谓是个系统纷繁的大工程. ...

随机推荐

  1. vue 错误分析

    1  点击事件发生的错误 原因是,重复触发事件函数导致   改为不一样的名字即可 2  提示 : “ vuex] Expects string as the type, but found undef ...

  2. Eclipse + ndk+ cocos2dx 调试Cocos2dx 程序

    本文是我自己尝试通过eclipse来在windows平台下搭建cocos2dx的过程,期间遇到了一些问题,都是通过网上借鉴别人的博文来解决的,下面也列出来这些参考文献.写下来的目的主要是自己以后要用的 ...

  3. Javascript面向对象编程(二):构造函数的继承 作者:yuan一峰

    Javascript面向对象编程(二):构造函数的继承   作者: 阮一峰 日期: 2010年5月23日 这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生 ...

  4. Ubuntu14.04 LTS 安装Chrome浏览器(转)

    add zhj: 亲测过,可以,原来不用FQ就可以下载,有点意外 原文:http://www.jianshu.com/p/8220578d0b15 1.打开终端(ctrl + alt + t),下载6 ...

  5. NOIP国王游戏

    #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #inc ...

  6. cors与jsonp

    在.net中,可以在webApiConfig代码里写,也可以在web.config里配置,但都需要引入System.Web.Cors.这些都是服务器端的配置,对整个项目有效. {若只想对某个请求有效, ...

  7. Centos安装elasticsearch教程

    elasticsearch安装是ytkah在做laravel电商站内搜索要实现的,通过自己的搜索和学习能力不算很费力解决了.下面就整理一下安装elasticsearch教程,服务器是Centos 7, ...

  8. 要继续看Python写算法的内容请到那里去

    由于在这里发文章的时候.莫名其妙的出现公布出去的问题.客服告知是由于链接或者敏感词. 能不能告诉我哪里出了问题?我能够改动,以便再发. 可是,没有人告诉我.仅仅是告诉我不能发. 另外,能不能公布一下敏 ...

  9. 误删除innodb ibdata数据文件 文件句柄 文件描述符 proc fd

    误删除innodb ibdata数据文件  文件句柄  文件描述符  proc  fd http://www.cnblogs.com/gomysql/p/3702216.html 提示:如果不小心通过 ...

  10. Got fatal error 1236原因和解决方法

    一 前言   MySQL 的主从复制作为一项高可用特性,用于将主库的数据同步到从库,在维护主从复制数据库集群的时候,作为专职的MySQL DBA,笔者相信大多数人都会遇到“Got fatal erro ...