Unity3D性能优化-图集制作插件TexturePacker中文教程

简介: 本文提供全流程,中文翻译。Chinar Unity图集制作插件-TexturePacker图文教程 学习如何使用 TexturePacker 为 Unity 制作图集 为新手节省宝贵的时间,避免采坑! 简单说就是:将大量的小图,合并到一张大图上,可以有效的降低 Drawcall 1.

Chinar blog www.chinar.xin

TexturePacker
Unity 图集制作工具


本文提供全流程,中文翻译

Chinar 的初衷是将一种简单的生活方式带给世人

使有限时间 具备无限可能

Chinar —— 心分享、心创新!

助力快速利用 C# 判断用户电脑联网状态

给新手节省宝贵的时间,避免采坑!


Chinar 教程效果:
8_


全文高清图片,点击即可放大观看 (很多人竟然不知道)


1

Intro —— 简介


为什么使用图集?

简单说就是:将大量的小图,合并到一张大图上,可以有效的降低 Drawcall

绘制一个图像需要提交图片(纹理)到显存,然后再进行绘制显示到屏幕上

在这个过程中 CPU 会产生一次 DrawCall ,也就是说绘制 88 张图片就要产生 88 次DrawCall

这显然非常消耗性能。图集就是为了解决此类问题

1. 减少性能消耗
2. 分类明确,易于管理
3.一次加载或者卸载完成多图片的处理,提高了运行效率

Unity 官方模糊了图集的概念,使开发者专注于开发,在打包时才会将图片进行合并

自行打包图集,网络大神各抒己见,皆有特色,想要官方的可以自行搜索

Chinar 的风格大家都懂,什么高效来什么!只为大家介绍更为好用的插件

我们今天的主角:TexturePacker、TexturePackerImporter


2

Download —— 下载、安装



TexturePacker 是一个独立的软件程序,支持多个引擎,安装后记得选择Unity平台

TexturePackerImporterUnity Store中免费插件,搜索下载导入工程即可

举个例子

点击下载 —— TexturePacker (官网)

点击下载 —— TexturePacker X64 (Chinar免费)
2_TexturePacker_
2_1_


3

Import Plugin —— 导入插件


TexturePacker 安装完成后,打开先不管,我们先来创建一个Unity工程,导入TexturePackerImporter

Ctrl+9 快捷键 打开 Asset Store 资源商店

→→搜索 TexturePacker Importer,下载并导入工程

先导入这个插件是为了适配之后 TexturePacker 生成并导入Unity 中的文件。直接进行处理,使一张大图自动切分
举个例子
3_TexturePacker_Importer


4

Texture usage —— 软件用法


我们回到 TexturePacker 软件界面,来简单学习下如何制作与导出文件

图片直接拖进来,算法会自动将所有小图切割合并到一张大图中,细节 Chinar 做的图已经很详细了

最后点击publish sprite sheet 会将生成的图集数据文件直接放到我们选择的目录中

(推荐直接放到 Unity 项目中。为了规范性,Chinar 放在了 Resources/Texture/Atlas 下)

举个例子
4_TexturePacker_
4_1_


5

Unity Project —— 项目数据


切换到 Unity 软件界面,等待文件编译

由于我们之前先导入了 TexturePacker Importer ,所以图片数据导入到 Unity 中会自动切分,我们只需直接使用即可

直接将sprite拖到UI image 组件上即可,用法上没什么不同

举个例子
5_0Unity_


6

dynamic loading —— 动态加载 Sprite


多数情况下,除了通过拖拽的方式,我们还需要用代码来动态的改变 UI 元素

很多大神,提出直接将UI做成预设物,通过加载预设的方式来实现动态改变UI。这样做有优点也有缺点,对于初学者来讲维护不方便,而且需要建立大量的预设物,量大后会造成不便。

Chinar 推荐方式:

注意: 需将图集文件放在 Resources / 其子目录下,用数据类型散列表(字典) Dictionary 来记录实现,动态加载图片
举个例子
6_Resources


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);
    }
}

8_


9

Share —— 项目分享



项目文件为 unitypackage 文件包:

下载导入 Unity 即可使用

举个例子
Git

CSDN (积分支持)

NetDisk (Chinar 免费)


10

AssetBundle —— AB包知识 (扩展)


如果是初学者不太了解 AssetBundle 知识的话

给大家提供2个教程。便于学习 打包、读取
举个例子

Unity 打包 AssetBundle 资源教程

Unity 读取 AssetBundle 资源教程(所有读取方式)


支持

May Be —— 开发者,总有一天要做的事!


拥有自己的服务器,无需再找攻略

Chinar 提供一站式《零》基础教程

使有限时间 具备无限可能!

Chinar 知你所想,予你所求!( Chinar Blog )


END

本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究

对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com

对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址

相关文章
|
5月前
|
图形学 开发者 存储
超越基础教程:深度拆解Unity地形编辑器的每一个隐藏角落,让你的游戏世界既浩瀚无垠又细节满满——从新手到高手的全面技巧升级秘籍
【8月更文挑战第31天】Unity地形编辑器是游戏开发中的重要工具,可快速创建复杂多变的游戏环境。本文通过比较不同地形编辑技术,详细介绍如何利用其功能构建广阔且精细的游戏世界,并提供具体示例代码,展示从基础地形绘制到植被与纹理添加的全过程。通过学习这些技巧,开发者能显著提升游戏画面质量和玩家体验。
211 3
|
5月前
|
图形学 数据可视化 开发者
超实用Unity Shader Graph教程:从零开始打造令人惊叹的游戏视觉特效,让你的作品瞬间高大上,附带示例代码与详细步骤解析!
【8月更文挑战第31天】Unity Shader Graph 是 Unity 引擎中的强大工具,通过可视化编程帮助开发者轻松创建复杂且炫酷的视觉效果。本文将指导你使用 Shader Graph 实现三种效果:彩虹色渐变着色器、动态光效和水波纹效果。首先确保安装最新版 Unity 并启用 Shader Graph。创建新材质和着色器图谱后,利用节点库中的预定义节点,在编辑区连接节点定义着色器行为。
353 0
|
5月前
|
传感器 开发工具 vr&ar
ManoMotion⭐二、Unity手势识别插件简介,及效果录屏
ManoMotion⭐二、Unity手势识别插件简介,及效果录屏
|
5月前
|
API 图形学
Unity精华☀️Audio Mixer终极教程:用《双人成行》讲解它的用途
Unity精华☀️Audio Mixer终极教程:用《双人成行》讲解它的用途
|
5月前
|
图形学
Unity精华☀️点乘、叉乘终极教程:用《小小梦魇》讲解这个面试题~
Unity精华☀️点乘、叉乘终极教程:用《小小梦魇》讲解这个面试题~
|
4月前
|
图形学 C++ C#
Unity插件开发全攻略:从零起步教你用C++扩展游戏功能,解锁Unity新玩法的详细步骤与实战技巧大公开
【8月更文挑战第31天】Unity 是一款功能强大的游戏开发引擎,支持多平台发布并拥有丰富的插件生态系统。本文介绍 Unity 插件开发基础,帮助读者从零开始编写自定义插件以扩展其功能。插件通常用 C++ 编写,通过 Mono C# 运行时调用,需在不同平台上编译。文中详细讲解了开发环境搭建、简单插件编写及在 Unity 中调用的方法,包括创建 C# 封装脚本和处理跨平台问题,助力开发者提升游戏开发效率。
356 0
|
4月前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
163 0
|
5月前
|
图形学 数据安全/隐私保护 iOS开发
Unity与IOS⭐Xcode打包,上架TestFlight的完整教程
Unity与IOS⭐Xcode打包,上架TestFlight的完整教程
|
5月前
|
Apache 图形学
WebGL☀️Unity WebGL适配到各平台的教程
WebGL☀️Unity WebGL适配到各平台的教程
|
5月前
|
开发工具 图形学 Android开发
Pico Neo 3教程☀️ 二、从 PicoVR Unity SDK 迁移至 Unity XR SDK
Pico Neo 3教程☀️ 二、从 PicoVR Unity SDK 迁移至 Unity XR SDK