一、什么是动态图集:
二、动态图集的优缺点:
unity 动态图集的优点包括:
unity 动态图集的缺点包括:
三、动态图集的实现方案:
本文不过多阐述关于动态图集的原理,直接上一个简单的demo来让大家来理解动态图集。
下面是动态图集的管理类:
using system.collections.generic;
using unityengine;
public class dynamicatlasmanager : monobehaviour
{
public int atlassize = 2048;
public textureformat textureformat = textureformat.rgba32;
public bool usemipmaps = false;
private static dynamicatlasmanager _instance;
public static dynamicatlasmanager instance
{
get
{
if (_instance == null)
{
gameobject go = new gameobject("dynamicatlasmanager");
_instance = go.addcomponent<dynamicatlasmanager>();
}
return _instance;
}
}
private dictionary<string, texture2d> _atlasdictionary;
private dictionary<string, rect> _spriterects;
private dictionary<string, sprite> _originalspritescache;
void awake()
{
_atlasdictionary = new dictionary<string, texture2d>();
_spriterects = new dictionary<string, rect>();
_originalspritescache = new dictionary<string, sprite>();
}
public void addspritestodynamicatlas(string atlasname, sprite[] sprites)
{
if (sprites == null || sprites.length == 0) return;
texture2d atlas;
if (_atlasdictionary.containskey(atlasname))
{
atlas = _atlasdictionary[atlasname];
}
else
{
atlas = new texture2d(atlassize, atlassize, textureformat, usemipmaps);
atlas.filtermode = filtermode.bilinear;
_atlasdictionary.add(atlasname, atlas);
}
for (int i = 0; i < sprites.length; i++)
{
if (!_originalspritescache.containskey(sprites[i].name))
{
_originalspritescache.add(sprites[i].name, sprites[i]);
}
}
int xoffset = 0;
int yoffset = 0;
int maxheight = 0;
for (int i = 0; i < sprites.length; i++)
{
sprite sprite = sprites[i];
texture2d spritetexture = sprite.texture;
if (xoffset + sprite.rect.width > atlas.width)
{
xoffset = 0;
yoffset += maxheight;
maxheight = 0;
}
// copy the texture using copytexture method
graphics.copytexture(spritetexture, 0, 0, (int)sprite.rect.x, (int)sprite.rect.y, (int)sprite.rect.width, (int)sprite.rect.height, atlas, 0, 0, xoffset, yoffset);
_spriterects[sprite.name] = new rect(xoffset, yoffset, sprite.rect.width, sprite.rect.height);
xoffset += (int)sprite.rect.width;
maxheight = mathf.max(maxheight, (int)sprite.rect.height);
}
}
public sprite getspritefromdynamicatlas(string atlasname, string spritename)
{
if (!_atlasdictionary.containskey(atlasname) || !_spriterects.containskey(spritename))
{
return null;
}
texture2d atlas = _atlasdictionary[atlasname];
rect spriterect = _spriterects[spritename];
// get the original sprite
if (!_originalspritescache.containskey(spritename))
{
return null;
}
sprite originalsprite = _originalspritescache[spritename];
// calculate the border of the new sprite based on the original sprite's border
vector4 border = originalsprite.border;
// create the new sprite with the correct border
return sprite.create(atlas, spriterect, new vector2(0.5f, 0.5f), originalsprite.pixelsperunit, 0, spritemeshtype.tight, border);
}
}
下面是动态图集的demo代码:
using unityengine;
using unityengine.ui;
public class dynamicatlasdemo : monobehaviour
{
public sprite sprite1;
public sprite sprite2;
public sprite sprite3;
public image image1;
public image image2;
public image image3;
private dynamicatlasmanager _dynamicatlasmanager;
void start()
{
_dynamicatlasmanager = dynamicatlasmanager.instance;
// add sprites to the dynamic atlas
_dynamicatlasmanager.addspritestodynamicatlas("demoatlas", new sprite[] { sprite1, sprite2, sprite3 });
image1.sprite = _dynamicatlasmanager.getspritefromdynamicatlas("demoatlas", sprite1.name);
image2.sprite = _dynamicatlasmanager.getspritefromdynamicatlas("demoatlas", sprite2.name);
image3.sprite = _dynamicatlasmanager.getspritefromdynamicatlas("demoatlas", sprite3.name);
}
}
优化前的draw call数量:5
优化后的draw call数量:3
备注:
上面的动态图集只是一个简单的方案,可以根据项目需求进行扩展和优化。
欢迎大家点赞评论关注三连,性能优化持续更新中。
发表评论