Atlas 介绍
Mesh 是用来描述物体的外形的,贴图用来描述物体的外观,之前提到过每个 Canvas 都会自动合并下面的所有元素到一个 Mesh 里面。Mesh 虽然可以合并,但是如果贴图是分开的,那么每个贴图依然会多占用一个 DrawCall。为了减少 DrawCall,我们可以把多张图片合并到一个图片中,也就是图集(Atlas)。
创建一个 Atlas
- 在 Editor Setting 中将 Sprite Packer 中的 Mode 设置为 Always Enabled。
- 在 Project 视图中通过 Create->Sprite Atlas 创建图集。
- 可以将单张图片或者整个文件夹拖到 Objects for Packing 中。注意所有贴图的格式都要是 Sprite(2D and UI)。
- 然后在 PC,Mac & Linux Standalone settings 中勾选 Override for PC,Mac & Linux Standalone,并设置图集大小和贴图压缩格式。
- 最后点击 Pack Preview。
效果如图所示:读取 Atlas
Atlas 可以把很多 Sprite 合并到一起,如果有元素在运行期间需要更换图片,那么需要先加载这个图集,然后通过名字去读取 Sprite,名字就是 Sprite 在 Project 视图中的文件名。(那我如果在场景面板将一个 Canvas 里面所有的元素都设置好了图片,并且在运行期间不需要改变的话,那么图集还有用吗?)
代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24// 文件名:Script_05_14.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.U2D; // SpriteAtlas
public class Script_05_14 : MonoBehaviour
{
public Image image;
private SpriteAtlas m_SpriteAtlas;
private void Awake()
{
m_SpriteAtlas = Resources.Load("New Sprite Atlas") as SpriteAtlas;
}
private void OnGUI()
{
if (GUILayout.Button("<size=20>通过 Atlas 更改 Image 图片</size>")) // 原来这里可以用 HTML 语法
{
image.sprite = m_SpriteAtlas.GetSprite("yaogan1");
Debug.Log(image.sprite);
}
}
}
但这里会发现图片分隔的地方带着点其他图片的边界,如下图所示:
Variant
新建一个图集,并且将 Type 设置为 Variant,然后将之前 Master 的图集放到 Master Atlas 中,Variant 图集没有自己的 Objects for Packing,所以他是 Master Atlas 的一份拷贝,可以设置不同的 Scale 和 压缩格式。
多图集管理
- 使用图集就是为了优化效率,避免过多的 DrawCall,但是图集也有大小限制。以移动平台为例,图集尽量不要超过 1024。如果图片太多,就要考虑将他们放到多个图集上。如果不同图集下的图片发生叠层(?)现象,那么 DrawCall 又会上去。
- 尽可能把复用性强的图片放到一个公共图集下,每个 UI 系统有一个自己的私有图集。(?)由于战斗部分是最容易发生卡顿的地方,所以战斗下的 UI 尽可能合并在一个图集上。一定要将 UI 动静分离,频繁发生改变的 UI 元素要放在一个 Canvas 下。
- 不是所有的图片都适合放到图集中。比如,几千个图标都放在一个图集中的话,如果游戏中只需要同时显示少部分图标,那么整个图集都会被载入内存中,图标的出现率有很高,所以那么大的图标图集内存几乎没机会释放,所以这一类的图片是不适合放到图集中的。
参考
知乎:一文看懂材质/纹理 Material, Texture, Shading, Shader 的区别
CSDN:map、mesh、texture、material 和 shader 的联系
Unity Manual:Variant Sprite Atlas