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. java高级精讲之高并发抢红包~揭开Redis分布式集群与Lua神秘面纱

    java高级精讲之高并发抢红包~揭开Redis分布式集群与Lua神秘面纱 redis数据库 Redis企业集群高级应用精品教程[图灵学院] Redis权威指南 利用redis + lua解决抢红包高并 ...

  2. js Dom对象的属性与方法

    1.对象集合:      (1).all[];      (2).images[];      (3).anchors[];      (4).forms[];      (5).links[];   ...

  3. rman checksyntax和解决RMAN-01009: syntax error: found "dot"

    在日常清归档时候执行脚本报错 RMAN-00552: syntax error in command line argumentsRMAN-01009: syntax error: found &qu ...

  4. LoadRunner录制脚本-基础

    1.启动LoadRunner.没有脚本则创建脚本,有脚本则可以运行压力测试 2.点击Create/Edit Scripts,如下图,可新建或打开已有脚本 3.选择要测系统的协议 4.生成脚本分四步 5 ...

  5. WebDriver一些常见问题的解决方法

    1.Exception NoSuchElementException: 解决方法: 1)检查目标element的locator 2)如果locator是正确的,尝试在查找element之前等待页面的加 ...

  6. ansible--我的几个报错

    我的几个报错: 1.远程复制失败 [root@localhost ~ ]#scp -r .ssh 192.168.10.145:/root/ root@192.168.10.145's passwor ...

  7. POJ2274 Long Long Message 字符串

    正解:SA/哈希+二分 解题报告: 传送门! 啊先放下翻译,,,?大意就有两个字符串,求这两个字符串的最长公共子串 先港SA的做法趴 就把两个子串拼接起来,然后题目就变成了求后缀的最长公共前缀了 所以 ...

  8. 七、Spring Boot 启动配置原理

    几个重要的事件回调机制 配置在META-INF/spring.factories ApplicationContextInitializer SpringApplicationRunListener ...

  9. java执行字符串数学表达式【记录】

    https://stackoverflow.com/questions/3422673/evaluating-a-math-expression-given-in-string-form 1. goo ...

  10. 认识程序的执行:从高级语言到二进制,以java为例

    java 高级编程语言,面向对象*.java是源码文件*.class是字节码文件,一种中间文件. JDK包含的基本组件包括: javac – 编译器,将源程序转成字节码 jar – 打包工具,将相关的 ...