当前位置:   article > 正文

Unity性能优化 - 动态图集_unity 动态图集

unity 动态图集

一、什么是动态图集:

Unity 动态图集是 Unity 引擎中用于处理游戏纹理优化的一种技术。它可以将多个纹理打包到一个图集中,减少游戏中需要加载的纹理数量,从而提高游戏性能。

在运行时,Unity 动态图集会根据游戏需要动态地生成纹理,并将它们打包到一个图集中,这样可以大幅降低游戏加载时间和内存占用。

二、动态图集的优缺点:

 Unity 动态图集的优点包括:

  1. 减少纹理加载时间:使用动态图集可以将多个纹理打包成一个图集,在运行时只需要加载一个纹理,从而减少加载时间和内存占用。
  2. 提高游戏性能:减少纹理加载时间和内存占用可以提高游戏性能,并使游戏在不同平台上更加稳定。
  3. 简化开发过程:Unity 动态图集可以自动管理纹理的打包和加载,简化了开发过程,减少了手动操作的需要。

 Unity 动态图集的缺点包括:

  1. 生成图集需要一定的计算资源:在生成动态图集时需要一定的计算资源,如果游戏中的纹理较多,可能会导致游戏卡顿或者运行缓慢。
  2. 需要调整纹理尺寸:在使用动态图集时,需要将不同尺寸的纹理进行调整,否则可能会导致纹理失真或者变形。
  3. 需要一定的配置和调试:使用动态图集需要一定的配置和调试,需要对游戏的纹理进行分类和打包,以便在运行时生成动态图集。

三、动态图集的实现方案:

本文不过多阐述关于动态图集的原理,直接上一个简单的demo来让大家来理解动态图集。

下面是动态图集的管理类:

  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. public class DynamicAtlasManager : MonoBehaviour
  4. {
  5. public int atlasSize = 2048;
  6. public TextureFormat textureFormat = TextureFormat.RGBA32;
  7. public bool useMipmaps = false;
  8. private static DynamicAtlasManager _instance;
  9. public static DynamicAtlasManager Instance
  10. {
  11. get
  12. {
  13. if (_instance == null)
  14. {
  15. GameObject go = new GameObject("DynamicAtlasManager");
  16. _instance = go.AddComponent<DynamicAtlasManager>();
  17. }
  18. return _instance;
  19. }
  20. }
  21. private Dictionary<string, Texture2D> _atlasDictionary;
  22. private Dictionary<string, Rect> _spriteRects;
  23. private Dictionary<string, Sprite> _originalSpritesCache;
  24. void Awake()
  25. {
  26. _atlasDictionary = new Dictionary<string, Texture2D>();
  27. _spriteRects = new Dictionary<string, Rect>();
  28. _originalSpritesCache = new Dictionary<string, Sprite>();
  29. }
  30. public void AddSpritesToDynamicAtlas(string atlasName, Sprite[] sprites)
  31. {
  32. if (sprites == null || sprites.Length == 0) return;
  33. Texture2D atlas;
  34. if (_atlasDictionary.ContainsKey(atlasName))
  35. {
  36. atlas = _atlasDictionary[atlasName];
  37. }
  38. else
  39. {
  40. atlas = new Texture2D(atlasSize, atlasSize, textureFormat, useMipmaps);
  41. atlas.filterMode = FilterMode.Bilinear;
  42. _atlasDictionary.Add(atlasName, atlas);
  43. }
  44. for (int i = 0; i < sprites.Length; i++)
  45. {
  46. if (!_originalSpritesCache.ContainsKey(sprites[i].name))
  47. {
  48. _originalSpritesCache.Add(sprites[i].name, sprites[i]);
  49. }
  50. }
  51. int xOffset = 0;
  52. int yOffset = 0;
  53. int maxHeight = 0;
  54. for (int i = 0; i < sprites.Length; i++)
  55. {
  56. Sprite sprite = sprites[i];
  57. Texture2D spriteTexture = sprite.texture;
  58. if (xOffset + sprite.rect.width > atlas.width)
  59. {
  60. xOffset = 0;
  61. yOffset += maxHeight;
  62. maxHeight = 0;
  63. }
  64. // Copy the texture using CopyTexture method
  65. 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);
  66. _spriteRects[sprite.name] = new Rect(xOffset, yOffset, sprite.rect.width, sprite.rect.height);
  67. xOffset += (int)sprite.rect.width;
  68. maxHeight = Mathf.Max(maxHeight, (int)sprite.rect.height);
  69. }
  70. }
  71. public Sprite GetSpriteFromDynamicAtlas(string atlasName, string spriteName)
  72. {
  73. if (!_atlasDictionary.ContainsKey(atlasName) || !_spriteRects.ContainsKey(spriteName))
  74. {
  75. return null;
  76. }
  77. Texture2D atlas = _atlasDictionary[atlasName];
  78. Rect spriteRect = _spriteRects[spriteName];
  79. // Get the original sprite
  80. if (!_originalSpritesCache.ContainsKey(spriteName))
  81. {
  82. return null;
  83. }
  84. Sprite originalSprite = _originalSpritesCache[spriteName];
  85. // Calculate the border of the new sprite based on the original sprite's border
  86. Vector4 border = originalSprite.border;
  87. // Create the new sprite with the correct border
  88. return Sprite.Create(atlas, spriteRect, new Vector2(0.5f, 0.5f), originalSprite.pixelsPerUnit, 0, SpriteMeshType.Tight, border);
  89. }
  90. }

 下面是动态图集的demo代码:

  1. using UnityEngine;
  2. using UnityEngine.UI;
  3. public class DynamicAtlasDemo : MonoBehaviour
  4. {
  5. public Sprite sprite1;
  6. public Sprite sprite2;
  7. public Sprite sprite3;
  8. public Image image1;
  9. public Image image2;
  10. public Image image3;
  11. private DynamicAtlasManager _dynamicAtlasManager;
  12. void Start()
  13. {
  14. _dynamicAtlasManager = DynamicAtlasManager.Instance;
  15. // Add sprites to the dynamic atlas
  16. _dynamicAtlasManager.AddSpritesToDynamicAtlas("DemoAtlas", new Sprite[] { sprite1, sprite2, sprite3 });
  17. image1.sprite = _dynamicAtlasManager.GetSpriteFromDynamicAtlas("DemoAtlas", sprite1.name);
  18. image2.sprite = _dynamicAtlasManager.GetSpriteFromDynamicAtlas("DemoAtlas", sprite2.name);
  19. image3.sprite = _dynamicAtlasManager.GetSpriteFromDynamicAtlas("DemoAtlas", sprite3.name);
  20. }
  21. }

优化前的draw call数量:5

优化后的draw call数量:3

 

 

备注:

上面的动态图集只是一个简单的方案,可以根据项目需求进行扩展和优化。

欢迎大家点赞评论关注三连,性能优化持续更新中。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/125731
推荐阅读
相关标签
  

闽ICP备14008679号