一、什么是动态图集:
Unity 动态图集是 Unity 引擎中用于处理游戏纹理优化的一种技术。它可以将多个纹理打包到一个图集中,减少游戏中需要加载的纹理数量,从而提高游戏性能。
在运行时,Unity 动态图集会根据游戏需要动态地生成纹理,并将它们打包到一个图集中,这样可以大幅降低游戏加载时间和内存占用。
二、动态图集的优缺点:
Unity 动态图集的优点包括:
- 减少纹理加载时间:使用动态图集可以将多个纹理打包成一个图集,在运行时只需要加载一个纹理,从而减少加载时间和内存占用。
- 提高游戏性能:减少纹理加载时间和内存占用可以提高游戏性能,并使游戏在不同平台上更加稳定。
- 简化开发过程: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
备注:
上面的动态图集只是一个简单的方案,可以根据项目需求进行扩展和优化。文章来源:https://www.toymoban.com/news/detail-538747.html
欢迎大家点赞评论关注三连,性能优化持续更新中。文章来源地址https://www.toymoban.com/news/detail-538747.html
到了这里,关于Unity性能优化 - 动态图集的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!