TexturePacker
Unity 图集制作工具
本文提供全流程,中文翻译
Chinar 的初衷是将一种简单的生活方式带给世人
使有限时间 具备无限可能
Chinar —— 心分享、心创新!
助力快速利用 C# 判断用户电脑联网状态
给新手节省宝贵的时间,避免采坑!
Chinar 教程效果:
全文高清图片,点击即可放大观看 (很多人竟然不知道)
1
Intro —— 简介
为什么使用图集?
简单说就是:将大量的小图,合并到一张大图上,可以有效的降低 Drawcall
绘制一个图像需要提交图片(纹理)到显存,然后再进行绘制显示到屏幕上
在这个过程中 CPU
会产生一次 DrawCall ,也就是说绘制 88 张图片
就要产生 88 次DrawCall
这显然非常消耗性能。图集就是为了解决此类问题
1. 减少性能消耗
2. 分类明确,易于管理
3.一次加载或者卸载完成多图片的处理,提高了运行效率
Unity 官方模糊了图集的概念,使开发者专注于开发,在打包时才会将图片进行合并
自行打包图集,网络大神各抒己见,皆有特色,想要官方的可以自行搜索
Chinar 的风格大家都懂,什么高效来什么!只为大家介绍更为好用的插件
我们今天的主角:TexturePacker、TexturePackerImporter
2
Download —— 下载、安装
TexturePacker
是一个独立的软件程序,支持多个引擎,安装后记得选择Unity平台
TexturePackerImporter
是Unity Store
中免费插件,搜索下载导入工程即可
点击下载 —— TexturePacker X64 (Chinar免费)
3
Import Plugin —— 导入插件
TexturePacker
安装完成后,打开先不管,我们先来创建一个Unity工程,导入TexturePackerImporter
Ctrl+9 快捷键 打开 Asset Store 资源商店
→→搜索 TexturePacker Importer
,下载并导入工程
先导入这个插件是为了适配之后 TexturePacker
生成并导入Unity 中的文件。直接进行处理,使一张大图自动切分
4
Texture usage —— 软件用法
我们回到 TexturePacker
软件界面,来简单学习下如何制作与导出文件
图片直接拖进来,算法会自动将所有小图切割合并到一张大图中,细节 Chinar 做的图已经很详细了
最后点击publish sprite sheet
会将生成的图集数据文件直接放到我们选择的目录中
(推荐直接放到 Unity 项目中。为了规范性,Chinar 放在了 Resources/Texture/Atlas 下)
5
Unity Project —— 项目数据
切换到 Unity
软件界面,等待文件编译
由于我们之前先导入了
TexturePacker Importer
,所以图片数据导入到 Unity 中会自动切分,我们只需直接使用即可
直接将sprite
拖到UI image
组件上即可,用法上没什么不同
6
dynamic loading —— 动态加载 Sprite
多数情况下,除了通过拖拽的方式,我们还需要用代码来动态的改变 UI 元素
很多大神,提出直接将UI做成预设物,通过加载预设的方式来实现动态改变UI。这样做有优点也有缺点,对于初学者来讲维护不方便,而且需要建立大量的预设物,量大后会造成不便。
Chinar 推荐方式:
注意: 需将图集文件放在 Resources / 其子目录下,用数据类型散列表(字典) Dictionary
来记录实现,动态加载图片
7
Lookup function —— 查找函数
我们需要一个查找函数,以便我们获取目标图集中的对应精灵
重点函数:
Object[] atlas = Resources.LoadAll(spriteAtlasPath);
目录中,图片数据 “Chinar”是一张.png
图片 ,需放在 Resources 目录下
因图片是单个文件, 如果用 Resources.Load只能返回一个 Object 对象,这里采用 Resources.LoadAll 返回Object[]
我封装了一个极简的静态通用函数,适用于内外部数据的读取,无需挂载直接调用
将获取
对应名称的 UI Sprite
简化到一行代码
LoadSprite(string atlasPath, string spriteName, bool isResources = true)
using UnityEngine;
using System.Collections.Generic;
/// <summary>
/// 静态函数,无需挂载
/// 主函数:LoadSprite()
/// </summary>
public class ChinarAtlas
{
private static readonly Dictionary<string, Object[]> _atlasDic = new Dictionary<string, Object[]>(); //图集字典
/// <summary>
/// 加载对应图集中,对应名称的精灵图片
/// </summary>
/// <param name="atlasPath">图集路径</param>
/// <param name="spriteName">精灵名称</param>
/// <param name="isResources">默认内部 Resources 加载,false 时,通过 AssetBundle 方式加载</param>
/// <returns>Sprite</returns>
public static Sprite LoadSprite(string atlasPath, string spriteName, bool isResources = true)
{
Sprite sprite = null; //字典中包含 目标图集
if (_atlasDic.ContainsKey(atlasPath)) sprite = SpriteFormAtlas(_atlasDic[atlasPath], spriteName); //得到该图集中对应名称的 Sprite
if (sprite != null) return sprite; //返回找到的 Sprite
Object[] atlas = isResources ? Resources.LoadAll(atlasPath) : AssetBundle.LoadFromFile(atlasPath).LoadAllAssets(); //选择内外部加载方式
_atlasDic.Add(atlasPath, atlas); //到字典中
sprite = SpriteFormAtlas(atlas, spriteName); //找到 Sprite
return sprite; //返回找到的 Sprite
}
/// <summary>
/// 删除图集缓存
/// </summary>
/// <param name="atlasPath">图集路径</param>
public static void DeleteAtlas(string atlasPath)
{
if (_atlasDic.ContainsKey(atlasPath)) _atlasDic.Remove(atlasPath);
}
/// <summary>
/// 遍历图集并找出 Sprite
/// </summary>
/// <param name="atlas">Object[]</param>
/// <param name="spriteName">精灵名称</param>
/// <returns>Sprite</returns>
private static Sprite SpriteFormAtlas(Object[] atlas, string spriteName)
{
foreach (var obj in atlas)
{
if (obj != null && obj is Sprite && obj.name == spriteName) return (Sprite) obj;
}
Debug.LogWarning("图集中未查找到名为:<" + spriteName + ">的精灵");
return null;
}
}
8
Dynamic loading usage —— 动态加载用法
直接调用函数 ChinarAtlas.LoadSprite(图集文件全路径,目标Sprite名称,(不填) 默认Resources加载/false 是AssetBundle)
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 动态读取数据、添加/改变UI元素
/// </summary>
public class ChinarDemo : MonoBehaviour
{
private AssetBundle ab; //AB包对象
public Image UiResourcesImage
{
get { return GameObject.Find("Resources Image").GetComponent<Image>(); }
}
public Image UiAssetBundleImage
{
get { return GameObject.Find("AssetBundle Image").GetComponent<Image>(); }
}
void Start()
{
ResourcesLoadMethod();
AssetBundleLoadMethod();
}
/// <summary>
/// 第一种:Resources加载 —— 内部
/// </summary>
private void ResourcesLoadMethod()
{
UiResourcesImage.sprite = ChinarAtlas.LoadSprite("Texture/Atlas/Chinar", "Chinar1");
}
/// <summary>
/// 第二种:AssetBundle加载 —— 外部
/// </summary>
private void AssetBundleLoadMethod()
{
UiAssetBundleImage.sprite = ChinarAtlas.LoadSprite(Application.streamingAssetsPath + "/ChinarAssetBundles/atlas/chinar.unity3d", "Chinar2", false);
}
}
9
Share —— 项目分享
项目文件为 unitypackage 文件包:
下载导入 Unity 即可使用
10
AssetBundle —— AB包知识 (扩展)
如果是初学者不太了解 AssetBundle 知识的话
Unity 读取 AssetBundle 资源教程(所有读取方式)
支持
May Be —— 开发者,总有一天要做的事!
拥有自己的服务器,无需再找攻略 Chinar 提供一站式《零》基础教程 使有限时间 具备无限可能! |
Chinar 知你所想,予你所求!( Chinar Blog )
END
本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究
对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com
对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址