赞
踩
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
上面的动态图集只是一个简单的方案,可以根据项目需求进行扩展和优化。
欢迎大家点赞评论关注三连,性能优化持续更新中。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。