这是第133篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。

UWA 问答社区:answer.uwa4d.com

UWA QQ群:465082844(仅限技术交流)

资源管理

Q:我有一个关于Crunch压缩图片的AssetBundle打包的问题,Unity官网的AssetBundle用法介绍里有一条,就是说因为使用Crunch压缩之后的图片,打成AssetBundle包再压缩,大小也基本不会有变化,还会导致打包慢+使用时候需要解压,所以建议不要压缩。

4.6.1. Crunch Compression

Bundles which consist primarily of DXT-compressed textures which use the Crunch compression algorithm should be built uncompressed.

但是我们打AssetBundle的时候,并没有针对每个AssetBundle选择压缩不压缩的选项,要么所有都压缩,要么所有都不压缩。所以按照“使用Crunch压缩的图片打包时建议不要压缩的思路”的话,我想到2种做法:

1)所有AssetBundle包都不压缩,不知道这会不会导致Texture以外的资源的AssetBundle包变大很多,如果有用过的人希望介绍下经验。

2)先用LZ4打所有包,然后备份AssetBundleManifest文件,再用不压缩方式打Crunch压缩的图片包,打完把之前备份的AssetBundleManifest覆盖回来,感觉这种做法有点怪,还会导致图片的AssetBundle包要打2次,延长打包时间。

想问一下有没有更好的做法?还是说只要不压缩就可以了?

A1:有时候有些选择的确比较纠结。让我选择的话可能直接都用LZ4的方式,毕竟LZ4自身牺牲了压缩率换取了“does not require the entire bundle to be decompressed before use”这种优势。Crunch压缩之后的贴图没有什么压缩空间,但是在LZ4中解压的时间也不是很长(具体需要题主自己测试下)。

AssetBundle不压缩我感觉是不太能接受的,之间简单看过整个包体会大挺多的,这个题主用你们工程试一下就知道了。两遍打包的过程,个人是觉得性价比比较低,而且可能隐含一些坑需要花点时间踩。对于打包来说,越简单的流程肯定越好。

因为用的项目还在Unity 5.6的版本,所以没有做过Crunch的相关测试,建议题主除了问大家的建议之外,也可以自己做测试真正验证下,比如确定下完全不压缩对于包体的影响,使用LZ4压缩和不压缩贴图对于加载的时长影响。相信有最真实的测试数据会让题主做决策时更加放心。

感谢贾伟昊@UWA问答社区提供了回答

A2:两种策略:

1)LZ4压缩,打包时间在可接受范围之内;
2)AssetBundle不压缩,将打包好的AssetBundle进行zip压缩,游戏第一次初始化时,解压缩到可读写目录,这样Unity直接读取未压缩的AssetBundle文件,也方便以后做统一的热更新管理。

感谢郑骁@UWA问答社区提供了回答

A3:楼上说的两种方式是主流方式,LZ4在包体和加载速度上有个好的平衡。自己压缩然后解压到可读写目录,用CreateFromFile方式加载,在内存和效率上都有优势,代价就是前面会有很长时间的解压过程,这个时候要给出界面响应,听闻如果时间过长没有游戏内容画面苹果爸爸可能会通不过。

感谢赵林@UWA问答社区提供了回答

该问答来自UWA问答社区,欢迎大家转至社区交流:

https://answer.uwa4d.com/question/5bc94e4b8af62a50acb8e0fd

渲染

Q:我使用MeshBaker,把全场景的同Shader物件,在合并Mesh总面数64K范围内,尽量合在一起。合并完Mesh后发现场景的DrawCall降低了, 但是发现Stats面板中面数翻了倍。貌似相机的视锥体剔除功能对MeshBaker合批完之后的无效。求教这个问题怎么破解?

A1:CPU送给GPU渲染之前的最小的单元是一个Mesh(或者一个Submesh?),所以如果你手动合并了Mesh,就意味着面数很大可能上会变多,这个是面数和DrawCall之间的取舍,所以建议根据项目瓶颈来选择一个合适的均衡点。

我们用的是Unity的Static Batch,可以降低Batches,面数不会增长,原理是合并成Submesh,并且进行排序,然后根据镜头依据Submesh进行裁剪。当然也有代价,包体和内存大小可能会多一些,然后因为只是做排序,会因为动态阴影等宏的设定导致被Batch被打断。

简答做个测试验证:2个Cube,合并之后:

旋转相机,视角内只有一个的情况下:

Demo比较简单,只做之前观点的验证,题主可以自己再做一个复杂的Demo来验证下。

天下没有免费的午餐。大部分优化都是有代价的,都是用另外的东西来换取,只是代价的性价比不同罢了。

感谢贾伟昊@UWA问答社区提供了回答

A2:如楼主所言,这时一个客观存在的事实。所以我会选择如下方案:

放弃静态批处理,进行手动合并,合并的方案根据视野距离分块,将小块中的Mesh在场景Load的时候进行合并,这样DrawCall数会增加,但不是很多,三角形会大量减少。

感谢郑骁@UWA问答社区提供了回答

A3:补充楼上,手工合并是会存在这个问题,但手工合并的时候可以自己控制粒度,但还是会带来不灵活的问题。Static Batch存在内存问题和包体增大的问题。

Unity提供了一种可以运行时合并的API StaticBatchingUtility.Combine,有两个重载
public static void Combine(GameObject staticBatchRoot);
public static void Combine(GameObject[] gos, GameObject staticBatchRoot);
可以使用这个API控制合并粒度,相当于静态合批,这个可以不增大包体,代价是内存和CPU开销。正如楼上说的,天下没有免费的午餐,优化大多时候是要付出另外的代价。

感谢赵林@UWA问答社区提供了回答

该回答来自UWA问答社区,欢迎大家转至社区交流:

https://answer.uwa4d.com/question/5bc951798af62a50acb8e0fe

内存

Q:我有个2018.2.13f1版本上用WWW加载AssetBundle的内存疑问。WWW加载内存记录如下:

初始:

www下载中:

www.assetbundle调用之后:

www.dispose之后

 

ab.unload之后

 

www.assetbundle调用之后,Mono增长36MB,Unity增加26.1MB, 这个26.1MB怎么理解?下载的AssetBundle文件是UnCompressed,大小36MB;

UWA:通过在群里跟题主要了LZ4和LZMA的内存测试数据,我们发现如下表格的内存统计在2018(也许2017.4)上已经不太准确了。

以题主的New WWW加载为例,在之前的加载36MB的UnCompressed AB时,其内存是36+36=72MB,而现在则是36+36+26=98MB

之前的72MB是全部统计在Unity中,现在是62MB在Unity中,而36MB在Mono中体现。

之所以出现这种情况,是因为Unity引擎在新版本中(暂时还无法考证具体是从2017哪个版本开始),New WWW加载AB会走www.bytes这个操作,然后通过LoadFromMemory来进行加载。这也是为什么36MB的Uncompressed在加载后,Mono会增加36MB,而后LZ4和LZMA的AB加载,Mono也都会增加与其Size一样的大小。

同时,多出来的26MB是由LoadFromMemory加载导致的,这里有个遗漏点需要补充下,即无论是36MB的UnCompressed AssetBundle还是10MB的LZMA AssetBundle,其www.assetbundle调用后,其Unity内存一项的增幅均为26MB,而如果是20MB的LZ4 AB的内存增幅则为20MB。这里面有两种推测。

1)LZ4 的AssetBundle bytes通过LoadFromMemory加载时,则直接转换成LZ4的AssetBundle来进行使用;而UnCompressed和LZMA则会被压缩成类似于LZ4的其他参数格式,所以内存会有所偏差。

2)无论是哪种压缩格式的bytes,都是转成LZ4格式,但UnCompressed和LZMA格式的数据是需要进一步执行数据转换的,因此,需要开辟一个Buffer来进行转换,所以多出来的6~7MB是Buffer所致。

当然,以上两种是在没有源码查看的情况下来进行推测的,个人比较倾向于第一种,但不排除有其他更多原因存在。后续,关于其他AssetBundle API的加载方式我们也都会进行大量测试,看来有很多内容需要更新了,如果社区其他朋友有做过类似测试或看过其他文章,也非常欢迎来进行指正和分享。

该回答由UWA提供,欢迎大家转至社区交流:

https://answer.uwa4d.com/question/5bcd3f4d01a33650b1f88981

UI

Q:目前我们在做台湾版本的多语言适配,也就是将简体版的改为繁体版的,目前不考虑图片尺寸的问题。目前需要适配的范围有:策划文字、UI文字、UI的单图、策划配置的单图、UI图集、策划配置的图集、UI Prefab、角色以及角色技能和特效。

关于策划文字和UI文字,我们都通过导入导出表格解决了,目前还剩下各种各样的图片,然后关于单图部分,在切换语言的时候,我遍历所有用到这些单图的Prefab、Asset,将引用修改为多语言版本的图片,也算是解决了。目前还剩下图集部分,我现在有两个想法:

一个是修改打图工具,在打图的时候筛选出不同语言的图片,选择当前语言的打包成一个图集,好处就是维护简单,不需要维护多份不同语言的图集,坏处就是打图的过程相对较慢,每次切换语言时间很长,然后不直观,不能对比两张图集之间的区别。

另一个方法就是,打两份图集,通过后缀来区分不同的语言,然后效仿单图的多语言解决方案,修改引用,好处就是打好了图片,如果没有修改不需要在切换的时候重新打包图片,速度快,方便对比,坏处就是需要维护两份图集,修改无多语言的图片需要同时修改两份图集,比较麻烦。

A1:我们没有其他语言的图集,做法是把图集中带文字的图片拆出来用Texture来根据语言加载,以后的新项目是从设计上规范不把带文字的图片放入图集。多份图集的问题是,如果要动态切换语言,还需要切换对应图集,资源和内存的冗余都需要考虑。

感谢林健@UWA问答社区提供了回答

A2:我们使用AssetBundle变种机制做的多语言,预设、图集、纹理都可以做变种,基本可以应对各种需求。好处是拖上去的引用不用换,Unity变种机制帮你搞定,坏处是有一个大硬伤编辑器下无法直接预览,必须先构建AssetBundle。

感谢littlesome@UWA问答社区提供了回答

A3:多语言版本不仅会涉及到图片及文字替换,也会出现排版问题,例如阿拉伯语。所以在设计上尽量居中显示并排版,这样问题是向两边扩散的,减少文字过长被遮挡的问题。多语言有些游戏是在游戏内切换,所以我会在游戏中加入对应的type,在资源加载时进行区分。

Prefab的引用可以如题主所述修改。图集规划可以解决大部分问题,但是部分细碎图片,我会选择打包成大图集,做好映射关系表,在动态加载时进行区分加载,避免对原资源造成过大改动。

感谢郑骁@UWA问答社区提供了回答

A4:以前我做的时候是文本,图集,Prefab,Audio等各种分开考虑,需要注意的问题就是各种语言的长度不同导致的排版,图集下各种语言放到一起然后打AsseBundle的时候做语言筛选,多语言图大小可能也存在不同,要注意图集的规划,不要出现分成两个图集的情况等。

现在我倾向的方案是用AssetBundle变种机制,这个要解决编辑器下预览问题,我们在编辑器模式和机器上走的加载流程不同,编辑器模式下走的加载Prefab显示,所以预览这个问题对我们项目来说并不存在。

感谢赵林@UWA问答社区提供回答

该回答来自UWA问答社区,欢迎大家转至社区交流:

https://answer.uwa4d.com/question/5bc5ae0d5c3fd06b3442ddc3

UI

Q:UGUI字体加粗后Android真机并没有加粗而且加宽导致文字重叠,网上没有找到解决方案。不知道该如何解决。

UWA:假如你用msyh,那你需要在资源里面同时放上msyh以及msyhbd,这样才能在UGUI中使用msyh的粗体,不然你得到的只有Unity自己加粗了的msyh。

该回答由UWA提供,欢迎大家转至社区交流:

https://answer.uwa4d.com/question/5bc59e7d5707da4d53bc3633

今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

【厚积薄发】Crunch压缩图片的AssetBundle打包的更多相关文章

  1. AssetBundle打包

    为热更新打基础(xlua\tolua) 素材.源码链接:http://www.sikiedu.com/course/74/task/1812/show 一.AssetBundle的定义和作用 1,As ...

  2. webpack2使用ch10-处理图片(png jpg svg 等) 限制图片 压缩图片

    1 目录展示 安装依赖 "file-loader": "^0.11.1", "image-webpack-loader": "^3 ...

  3. Unity3d 5.x AssetBundle打包与加载

    1.AssetBundle打包 unity 5.x版本AssetBundle打包,只需要设置好AssetBundle的名称后,unity会自动将其打包,无需处理其他,唯独需要做的是设置好个AssetB ...

  4. Unity之AssetBundle打包

    AssetBundle Resources:表示U3D自动将资源打成一个AssetBundle包,所有放在Resources下的文件夹都会打成一个AssetBundle包,资源非常大,Resource ...

  5. .NET压缩图片保存 .NET CORE WebApi Post跨域提交 C# Debug和release判断用法 tofixed方法 四舍五入 (function($){})(jQuery); 使用VUE+iView+.Net Core上传图片

    .NET压缩图片保存   需求: 需要将用户后买的图片批量下载打包压缩,并且分不同的文件夹(因:购买了多个用户的图片情况) 文章中用到了一个第三方的类库,Nuget下载 SharpZipLib 目前用 ...

  6. .NET压缩图片保存

    需求: 需要将用户后买的图片批量下载打包压缩,并且分不同的文件夹(因:购买了多个用户的图片情况) 文章中用到了一个第三方的类库,Nuget下载 SharpZipLib 目前用的 1.1的版本 效果: ...

  7. Unity5 AssetBundle打包加载及服务器加载

    Assetbundle为资源包不是资源 打包1:通过脚本指定打包 AssetBundleBuild ab = new AssetBundleBuild                         ...

  8. Unity5.X 新版AssetBundle打包控制

    一.什么是AssetBundle 估计很多人只知道Unity的模型之类的东西可以导出成一种叫做AssetBundle的文件,然后打包后可以在Unity程序运行的时候再加载出来用.那么AssetBund ...

  9. [Unity3D] 5.0 图集合并扩展工具,用于解决UGUI与AssetBundle打包造成资源包过大的问题

    [Unity3D] 5.0 图集合并扩展工具,用于解决UGUI与AssetBundle打包造成资源包过大的问题 2017年07月05日 15:57:44 阅读数:1494 http://www.cpp ...

随机推荐

  1. php 访问控制和重载

    一     php 类中定义的private/protected属性,类外部是无法访问的,但是 我们可以通过public方法来访问设置这些属性 如下 <?php class test{ priv ...

  2. OpenStack虚拟机快照和增量备份实现

    1 快照的概念一般对快照的理解就是能够将系统还原到某个瞬间,这就是快照的作用.快照针对要保存的数据分为内存快照和磁盘快照,内存快照就是保存当前内存的数据,磁盘快照就是保存硬盘的数据.快照针对保存方式又 ...

  3. React 异步组件

    之前写过一篇 Vue 异步组件的文章,最近在做一个简单项目的时候又想用到 React 异步组件,所以简单地了解了一下使用方法,这里做下笔记. 传统的 React 异步组件基本都靠自己实现,自己写一个专 ...

  4. Regular Expression Patterns

    Regular Expression Patterns Following lists the regular expression syntax that is available in Pytho ...

  5. ubuntu配置默认python版本并安装pip

    ubuntu 16.04本身是自带python的,他本身是自带2.X和3.X,两个版本,默认的是2.X.这里记录一下如果在版本间切换以及如何把python版本切换到3.X下的方法. 1.查看Ubunt ...

  6. 20145203盖泽双 《Java程序设计》第9周学习总结

    20145203盖泽双 <Java程序设计>第9周学习总结 教材学习内容总结 1.撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找. 2.JDBC目的:让Java程序设 ...

  7. koa2怎么自定义一个中间件

    首先定义一个方法 function test(ctx){ global.console.log('m1') } 把这个中间件导出去 module.exports=function(){ return ...

  8. leetcode566. Reshape the Matrix

    https://leetcode.com/problems/reshape-the-matrix/description/ public int[][] matrixReshape(int[][] n ...

  9. linux定时任务-crontab

    使用场景: 有时候线上服务器挂了,或者一些数据推送不正常,一般来说我们需要做的就是将项目重启运行,或者检查核对出问题的位置,来快速解决,很多时候我们不得不登上服务器来查看,这个对于目前工作日益繁忙的我 ...

  10. day 94 Django学习之django自带的contentType表

    Django学习之django自带的contentType表   通过django的contentType表来搞定一个表里面有多个外键的简单处理: 摘自:https://blog.csdn.net/a ...