说到UI优化,很多人对其并不以为意,UI的制作无非使用UGUI或者NGUI。UI优化主要是针对图集,还有一些依赖项的优化,针对的是内存优化,上面这些都是关于静态UI的优化,这个是作为程序员都要经历的阶段。其实很多开发者对使用UGUI或者NGUI已经墨守成规了,我们如果真想去优化,其实完全可以自己封装一套UI的底层代码,效率很高的,摒弃了UGUI和NGUI影响效率的代码,自己封装的简单实用,在我的视频课程——飞车竞速
在这个游戏中使用的UI都是自己封装的,游戏 UI底层代码封装如下所示:

这个UI底层封装的是针对我们项目的需求开发的,在这里是给读者拓展一下思路,UI优化并不仅限于图集和图片大小的优化,代码层面也是可以做的。
以上给读者介绍的都是关于静态UI的制作与优化,本篇博客主要是给读者介绍一下关于UI的动态图片优化,首先明白什么是动态加载图片,比如我们创建的角色ICON,还有游戏生成的怪物ICON等等,就是说这些ICON不是事先就有的,而是根据游戏动态加载到场景中的,我们的优化就是针对这些动态加载的ICON去做优化,在程序运行的过程中打图集,下面我们先实现一个2D动作播放的动态图集生成的Demo。
在Unity中如下图所示:

上图就是我们常见的序列帧动画,它的制作方式很多,我们可以事先将其打成图集,按照顺序播放,也可以直接播放,我们接下来实现的是动态的加载,动态的打图集算法。我们实现的思路是首先获取到需要打图集的图片,然后将其按照顺序依次在已创建的空白图片上把序列帧图片粘贴上,同时我们还需要使用一个Json文件记录我们对应图片的信息,这个信息非常重要,它主要目的是帮助我们找到对应的图片,这个信息包含:图片所在位置,图片的宽,高,图片的名字。
这样我们就完成了图集的动态生成,接下来就是逻辑代码的编写了。
第一步:获取动态加载的文件,在这里我们是将其拷贝到一个指定的目录下面,方便我们打图集,这个目录我们自己指定,就是模拟程序运行时动态获取到图片,然后去加载,代码如下:

        CopyPasteFoldersAndPNG(Application.dataPath + "/SpriteGenerator/Demos/Sprites", Application.persistentDataPath);string[] files = Directory.GetFiles(Application.persistentDataPath + "/Textures", "*.png");

第二步:定义图集大小,将获取到的图片在图集上进行排列, 核心算法如下:

protected IEnumerator createPack(string savePath = "") {if (savePath != "") {if (deletePreviousCacheVersion && Directory.Exists(Application.persistentDataPath + "/AssetPacker/" + cacheName + "/"))foreach (string dirPath in Directory.GetDirectories(Application.persistentDataPath + "/AssetPacker/" + cacheName + "/", "*", SearchOption.AllDirectories))Directory.Delete(dirPath, true);Directory.CreateDirectory(savePath);}List<Texture2D> textures = new List<Texture2D>();List<string> images = new List<string>();foreach (TextureToPack itemToRaster in itemsToRaster) {WWW loader = new WWW("file:///" + itemToRaster.file);yield return loader;textures.Add(loader.texture);images.Add(itemToRaster.id);}int textureSize = allow4096Textures ? 4096 : 2048;List<Rect> rectangles = new List<Rect>();for (int i = 0; i < textures.Count; i++)if (textures[i].width > textureSize || textures[i].height > textureSize)throw new Exception("A texture size is bigger than the sprite sheet size!");elserectangles.Add(new Rect(0, 0, textures[i].width, textures[i].height));const int padding = 1;int numSpriteSheet = 0;while (rectangles.Count > 0) {Texture2D texture = new Texture2D(textureSize, textureSize, TextureFormat.ARGB32, false);Color32[] fillColor = texture.GetPixels32();for (int i = 0; i < fillColor.Length; ++i)fillColor[i] = Color.clear;RectanglePacker packer = new RectanglePacker(texture.width, texture.height, padding);for (int i = 0; i < rectangles.Count; i++)packer.insertRectangle((int) rectangles[i].width, (int) rectangles[i].height, i);packer.packRectangles();if (packer.rectangleCount > 0) {texture.SetPixels32(fillColor);IntegerRectangle rect = new IntegerRectangle();List<TextureAsset> textureAssets = new List<TextureAsset>();List<Rect> garbageRect = new List<Rect>();List<Texture2D> garabeTextures = new List<Texture2D>();List<string> garbageImages = new List<string>();for (int j = 0; j < packer.rectangleCount; j++) {rect = packer.getRectangle(j, rect);int index = packer.getRectangleId(j);texture.SetPixels32(rect.x, rect.y, rect.width, rect.height, textures[index].GetPixels32());TextureAsset textureAsset = new TextureAsset();textureAsset.x = rect.x;textureAsset.y = rect.y;textureAsset.width = rect.width;textureAsset.height = rect.height;textureAsset.name = images[index];textureAssets.Add(textureAsset);garbageRect.Add(rectangles[index]);garabeTextures.Add(textures[index]);garbageImages.Add(images[index]);}foreach (Rect garbage in garbageRect)rectangles.Remove(garbage);foreach (Texture2D garbage in garabeTextures)textures.Remove(garbage);foreach (string garbage in garbageImages)images.Remove(garbage);texture.Apply();if (savePath != "") {File.WriteAllBytes(savePath + "/data" + numSpriteSheet + ".png", texture.EncodeToPNG());File.WriteAllText(savePath + "/data" + numSpriteSheet + ".json", JsonUtility.ToJson(new TextureAssets(textureAssets.ToArray())));++numSpriteSheet;}foreach (TextureAsset textureAsset in textureAssets)mSprites.Add(textureAsset.name, Sprite.Create(texture, new Rect(textureAsset.x, textureAsset.y, textureAsset.width, textureAsset.height), Vector2.zero, pixelsPerUnit, 0, SpriteMeshType.FullRect));}}OnProcessCompleted.Invoke();}

代码虽然比较长,但是理解起来不难,没有用任何算法,它只是按照顺序去排列,然后保存成图集和json文件,最终的图集如下所示:

Json文件如下所示:

{"assets":[{"x":0,"y":0,"width":286,"height":387,"name":"walking0004"},{"x":0,"y":388,"width":286,"height":387,"name":"walking0005"},{"x":0,"y":776,"width":286,"height":387,"name":"walking0003"},{"x":0,"y":1164,"width":286,"height":387,"name":"walking0001"},{"x":0,"y":1552,"width":286,"height":387,"name":"walking0002"},{"x":287,"y":0,"width":286,"height":387,"name":"walking0006"},{"x":287,"y":388,"width":286,"height":387,"name":"walking0010"},{"x":287,"y":776,"width":286,"height":387,"name":"walking0011"},{"x":287,"y":1164,"width":286,"height":387,"name":"walking0009"},{"x":287,"y":1552,"width":286,"height":387,"name":"walking0007"},{"x":574,"y":0,"width":286,"height":387,"name":"walking0008"}]}

接下来就是播放动画了,也就是最后一步。
第三步:播放动画逻辑代码实现如下:

    IEnumerator LoadAnimation() {Sprite[] sprites = assetPacker.GetSprites("walking");int j = 0;while (j < sprites.Length) {anim.sprite = sprites[j++];yield return new WaitForSeconds(0.1f);if (j == sprites.Length)j = 0;}}

实现效果如下所示:

这样就完成了动态图集的生成,当然我们还可以生成大的图集,这个一般在端游中使用的,效果如下图所示:

以上是关于动态图集的生成,我们测试了一下实现500个矩形,类似500个小ICON,花费时间是8ms,非常理想。该技术可以应用到项目开发中。。。。。。
项目下载地址:链接:https://pan.baidu.com/s/1bV6hepy2H6t1Xnzg88JOdg 密码:tybj

游戏UI动态加载图片优化相关推荐

  1. Delphi FastReport动态加载图片

    Delphi  FastReport动态加载图片 2011-01-06         作者:李海彬 阅读:684 以前用FastReport制作报表,从来没有打印过图片,这段时间做了个打印个人简历的 ...

  2. vue+elementui 中src动态加载图片的时候不起作用

    vue+elementui 中src动态加载图片的时候不起作用 代码如下: <el-table-column align="center" label="宠物图片& ...

  3. vue 动态加载图片路径报错解决方法

    vue 动态加载图片路径报错解决方法 参考文章: (1)vue 动态加载图片路径报错解决方法 (2)https://www.cnblogs.com/qingcui277/p/8930507.html ...

  4. jQuery页面滚动 动态加载图片等元素

    相信大家见过好多随着页面滚动,动态加载图片等元素的网站,我也是,以前见了好多,只是没时间去研究,今天晚上有空,百度了一下找了一个jquery插件,作者张鑫旭,效果挺好,代码也很简单,使用更方便,废话不 ...

  5. 解决问题:swiper动态加载图片后无法滑动

    解决问题:swiper动态加载图片后无法滑动 参考文章: (1)解决问题:swiper动态加载图片后无法滑动 (2)https://www.cnblogs.com/yangguoe/p/9857398 ...

  6. html5动态加载图片和加载视频

    这两在做一个动态加载图片的东西,有点类似QQ发说说里面附带图片的那种,经过测试可以任意添加.删除,然后该删除的位置被后一位自动填充,还有一个bug,就是最后一个图片的控件没做处理,删掉最后一个就会导致 ...

  7. RecyclerView使用 及 滑动时加载图片优化方案

    RecyclerView使用 及 滑动时加载图片优化方案 简述 本篇博文主要给大家分享关于RecyclerView控件的使用及通过继承RecyclerView来实现滑动时加载图片的优化方案,也同样能解 ...

  8. 动态加载图片,实现瀑布流效果

    瀑布流 1.瀑布流 瀑布流,可以有多列,每一列的高度可以不相同,但是宽度必须一样: 排列的方式是,从左往右排列,哪一列总高度最小,就优先排序,把图片放在这一列. 这样排完所有的图片后,可以保证每一列的 ...

  9. viewer动态加载图片第一次点击预览图片失败的问题

    如果您搜到这篇文章的话,那估计您遇到跟我一样的问题了. 众所周知,每一个插件都有很多坑,比如说市面上比较火爆的 图片浏览插件viewer,有js版本和jqery版本的,尽管这两个版本不一样,但是大同小 ...

最新文章

  1. AI 芯片的分类及技术
  2. ubuntu设置自启动服务程序
  3. 如何搭建企业局域网共享
  4. Ubuntu 搭建 GitLab 笔记 ***
  5. 【数据结构的魅力】001.认识复杂度二分法异或运算
  6. 黑马程序员全套Java教程_Java基础入门视频教程零基础自学Java必备教程视频讲义(3)
  7. 树莓派与阿里云服务器进行socket通信
  8. 果然天蝎座的人积分落户最容易...
  9. 周记——20151221
  10. ctab提取dna流程图_CTAB法提取植物DNA原理以及步骤
  11. 使用VNC连接树莓派4b如何全屏1080p分辨率,一次更改永久有效!
  12. 基于单片机的语音风扇的设计与实现
  13. 追爱系列电影电视剧书籍
  14. 前端切图案例课程一则-姜威-专题视频课程
  15. 导出百度网盘共享文件库目录清单的脚本
  16. 本周言论 之 C2C模式
  17. 网页版ASN1解码工具使用教程
  18. java获取屏幕_抓取当前屏幕信息
  19. Android 9(Pie) 新特性介绍
  20. 每年降本100万元+!企业研发管理该怎么做?

热门文章

  1. 自己定义头像处理,轻巧有用,非常多强大的小技巧在里面哦,快来赞美我一下吧^_^...
  2. kali安装无线网卡安装过程,RTL8812BU网卡,其他网卡安装同理,更换驱动文件即可
  3. 苹果原全球副总裁戈峻入职天九共享集团
  4. android listview qq,Android中使用listview实现qq/微信好友列表
  5. VSCode 搜索所有中文
  6. 软件开发常见模型(瀑布模型、V模型、W模型、敏捷开发模型)
  7. 《黑客攻防技术宝典Web实战篇》.Dafydd.Stuttard.第2版中文高清版pdf
  8. 小程序苹果手机地图授权问题
  9. redis构建微博(redis应用构建篇)
  10. Android闲鱼版本大全,闲鱼下载2021安卓最新版_手机app官方版免费安装下载_豌豆荚...