Unity性能优化 - 动态图集

这篇具有很好参考价值的文章主要介绍了Unity性能优化 - 动态图集。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、什么是动态图集:

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

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

二、动态图集的优缺点:

 Unity 动态图集的优点包括:

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

 Unity 动态图集的缺点包括:

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

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

本文不过多阐述关于动态图集的原理,直接上一个简单的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

unity 动态图集,Unity-性能优化,unity,游戏引擎

优化后的draw call数量:3

unity 动态图集,Unity-性能优化,unity,游戏引擎 

 

备注:

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

欢迎大家点赞评论关注三连,性能优化持续更新中。文章来源地址https://www.toymoban.com/news/detail-538747.html

到了这里,关于Unity性能优化 - 动态图集的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Unity编辑器扩展】包体优化神器,图片压缩,批量生成图集/图集变体,动画压缩

    功能介绍: 1. 压缩工具支持对图片原文件压缩(支持png/jpg),也支持使用Unity内置图片压缩批量对图片设置压缩参数。 2. 支持以文件夹或及其子文件夹为单位批量生成图集(SpriteAtlas), 支持同时生成图集变体(SpriteAtlas Variant),支持忽略像素宽高大于限定值的图片打进图集。 3. 批

    2023年04月10日
    浏览(33)
  • 【Unity Optimize】使用图集(Sprite Atlas)优化项目

    Unity中的图集(Sprite Atlas)是一种用于优化游戏性能和内存的纹理集。Sprite Atlas 可以应用于 2D 和 3D 项目中的 UI、粒子系统、贴图等等。 使用Unity可以很方便地创建Sprite Atlas,只需要创建一个Sprite Atlas GameObject,然后将纹理分配给它。在创建Sprite Atlas时,需要将纹理名称按角色

    2024年02月14日
    浏览(27)
  • 顶级工程师教你移动端游戏性能优化!Unity官方教程!

    ** 本期将给大家介绍如何提高资源、项目配置和图形的性能。所有教程均来自Unity官方,感兴趣的朋友可以去Unity官网查看完整教学内容。 降低或禁用 Accelerometer Frequency(加速度计频率) Unity每秒钟是会以一定次数统计移动设备的加速度计状态的。如果我们的程序不会用到加

    2024年02月20日
    浏览(35)
  • 【Unity3D赛车游戏优化篇】【十】汽车粒子特效和引擎咆哮打造极速漂移

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :Unity游戏demo – 😶‍🌫️版本: Unity2021 😶‍🌫️适合人群:Unity初学者进阶 😶‍🌫️学习目标:3D赛车游戏的基础制作 😶‍🌫️技能

    2024年02月09日
    浏览(45)
  • Unity 性能优化的手段(对象池、静/动态批处理、GPU实例化、垃圾回收、LOD、LightMap)【更新中】

    目录 对象池 扩容策略 收缩策略 DrawCall DrawCall的过程 为什么减少DrawCall可以实现性能优化? 减少Draw Call的方法 静态批处理(Static Batching) 动态批处理(Dynamic Batching) GPU Instancing(GPU实例化)​​​​​​​ 贴图集 垃圾回收的优化 垃圾回收的性能影响 延迟垃圾回收 避免

    2024年02月04日
    浏览(27)
  • Android性能优化之游戏引擎初始化ANR

    近期,着手对bugly上的anr 处理,记录下优化的方向。 借用网上的一张图: 这里的anr 问题是属于主线程的call 耗时操作。需要使用trace 来获取发生anr前一些列的耗时方法调用时间,再次梳理业务,才可能解决。 问题1 java 调用栈: 从调用栈中发现onActivityResult()执行对游戏侧的

    2024年02月15日
    浏览(40)
  • 十八、Unity游戏引擎入门

    1、下载     首先需要下载Unity Hub,下载网址:https://unity.com/cn。     然后在其中下载Unity编辑器并安装,可选择最新版本。     接着需要选择适合的开发环境,例如Android Studio或Xcode,以便进行手机游戏开发。在安装完Unity后,需要根据项目需求下载对应的模块和插件,例

    2024年02月16日
    浏览(51)
  • 使用团结引擎开发Unity 3D射击游戏

           本案例是初级案例,意在引导想使用unity的初级开发者能较快的入门,体验unity开发的方便性和简易性能。       本次我们将使用团结引擎进行开发,帮助想体验团结引擎的入门开发者进行较快的环境熟悉。      本游戏是一个俯视角度的射击游戏。主角始终位于屏幕

    2024年01月19日
    浏览(52)
  • C# 性能优化和Unity性能优化

    C# 性能优化是一个非常广泛的话题,需要从各个方面来考虑,包括算法和数据结构、编译器优化、代码优化等等。下面是一些常见的 C# 性能优化技巧: 选择正确的数据结构:C# 提供了各种不同的数据结构,例如数组、列表、字典等等。选择正确的数据结构可以大大提高代码

    2024年02月10日
    浏览(33)
  • Unity、UE、Cocos游戏开发引擎的区别

    Unity、Unreal Engine(UE)和Cocos引擎是三个常用的游戏开发引擎,它们在功能和特性上有一些区别。以下是它们之间的主要区别: 编程语言:Unity使用C#作为主要的编程语言,开发者可以使用C#脚本进行游戏逻辑编写。Unreal Engine主要使用C++作为编程语言,但也支持蓝图系统,允许

    2024年02月22日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包