1)关于 Addressable 打包大小的疑问
2)华为机型上人物模型锯齿严重问题
3)Unity 2019 图片压缩格式选择
4)Splash 用到的纹理常驻内存
5)新版 TileMap 的重叠面渲染问题


UWA 问答社区:answer.uwa4d.com
UWA QQ 群 2:793972859(原群已满员)

Addressable

Q:如何得到 Addressable 打出的 AssetBundle 的文件大小?Addressable 是通过把各个资源设置到各个 Group 中,而 Group 在设置这些资源时,可以打到一个 AssetBundle 还是要分开打呢?后续实际打包 AssetBundle,相当于是黑盒不透明的,但实际应该有这个需求,对于打出来的 Bundle 过大或者过小都不合适。我尝试基于它的 AnalyzeRule,写自定义的检查类,却没有发现跟 AssetBundle 有关的 API。大家知道是为什么吗?或者能知道它的 Catalog 相关的 API 也可以。

A:可以写一个 CustomBuildMode 继承 BuildScriptPackedMode,重写里面的 Name 和 DoBuild,这样每次打包都可以看到每个组生成的 Bundle 的大小,具体代码如下:

写完代码后,创建一个 CustomBuildMode.asset,并加入到 AddressableSettings 的 Build And Play Mode 里面,然后就可以进行 Build 并看到 Bundle 的大小了。


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


Rendering

Q:我们的游戏在华为机型上的模型贴图都很模糊,锯齿非常严重,但在其它机型上就没有这个问题。我们在系统设置中关闭了智能分辨率,效果就好很多。大家有遇到过类似的问题吗?怎么解决呢?我查看华为的官方论坛,发现这个问题似乎是个通病。

A:1.华为机型开启智能分辨率,会导致游戏运行时分辨率较低,从而导致模型贴图都较为模糊。在游戏一启动的时候读取设备的物理分辨率,执行 Screen.SetResolution 强制设置分辨率就能够正常显示。

2.如何正确地获取设备物理分辨率?在降低分辨率之后, 通过 Android API 获取到的设备分辨率都是降低之后的分辨率值。

3.尝试之后,发现了 getRealMetrics,调用这个接口获取分辨率(降低之后的分辨率值),再通过 density 值判断,若为 2,即这是被降低分辨率的值。

所以最后处理方式为:游戏一启动判断是华为的机型设备, 通过 getRealMetrics 获取屏幕分辨率,再通过 density 值判断是否被智能降低了,如果值为 2,将获取到分辨率值扩大 1.5 倍(基本上就是真实分辨率),然后用 SetResolution 设置。

用这个方法在华为设备上测试均正常显示(目前还没发现显示有异常)。

感谢极致游戏@UWA问答社区提供了回答


Texture

Q:向大家请教一下关于图片压缩格式选择问题。我看了之前的博客,安卓选择的是 ETC2,苹果选择的是 PVRTC。现在项目升级到了 Unity 2019.2.21f1 后,多了很多格式。

请教一下下面几个问题,Unity 版本是 2019.2.21f1:
1. 新版本 Unity 2019 Format 中安卓和苹果的格式,该怎么选择?
2. 安卓现在可以使用 ASTC 格式了吗?市场份额是多少?
3. Resize Algorthm 和 Override ETC2 fallback 分别代表什么意思?以及怎么选择?
4. HDR、6X6 和 10X10,该怎么选择好呢?
麻烦科普下,谢谢!


A1:第一个问题,个人觉得 iOS 选 ASTC,Android 选 ETC2 比较好。
第三和第四个问题,我建议可以看看官方文档:Texture 的文档,看完这个你基本上就能够明白了。然后根据项目需求,相信能够有个比较好的选择。
感谢李星@UWA问答社区提供了回答

A2:现在 Texture 新上线的项目已经开始普及 ASTC 的使用了,所以全面选择 ASTC,2019 可以默认 import 的时候选择 ASTC,尤其是对光照贴图和法线有很好的效果。Unity 现在默认是 6x6,也可以根据项目选择其它大小。
感谢郑骁@UWA问答社区提供了回答

A3:现在立项的项目,iOS 和安卓都应该选择 ASTC 了,因为连模拟器都已经支持 ASTC,我们的项目由于需要做 PBR 效果,ETC2 在压缩上的失真还是会比较严重的。如果实在需要兼容原来的机器(不支持 ASTC),可以多编译一份 ETC2 的资源放到服务器上,判断机型后再下载就行了,毕竟这部分机器很少。我自己的项目是这么做的,后台监控到需要下载 ETC2 资源的玩家也是少之又少。
感谢简单就好@UWA问答社区提供了回答

A4:如果版本包不发东南亚、中东、非洲和南美,那基本上全都可以用 ASTC 了;如果要发以上旧机型多的地区,建议用 Unity 默认的方案(pvrtc @ ios & etc @ android)。

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


Memory

Q:Splash 用到的纹理会一直常驻内存,应该怎么处理?

A1:测试后发现在 Unity 2017.4.33 和 Unity 2018.4.12 中都有这个问题,而且切换场景后,仍旧不会被卸载。

可以通过如下的方式解决这个问题:初始场景中,在脚本中引用 Splash 中用到的 Sprite,然后强制 Unload 这些 Sprite,可以去除这些纹理的占用,大致方式如下图:


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

A2:还有个方案:不用 Unity 提供的游戏内闪屏,改用平台原生方式实现。

iOS 上用 Storyboard 方式:


安卓上改一下 Java 代码,自己放个 View 挡在前面。

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


Rendering

Q:为了让新版的 TileMap 受到光照影响,替换 TileMap 为 LitShader,并且做了以下操作:
1. TileMap 的 mode 为 Chunk(块渲染)。
注:Individual 模式下不存在该问题,因为每个地块都是独立渲染的,但是 Draw Call 很高。
2. 打了一个平行光和聚光灯。

出现了问题,平行光下所有的 Tile 渲染正常,聚光灯渲染范围则重叠面,渲染不正常(不同于 zfighting),这是为什么呢?

以下为 Shader 截图:

正常渲染,仅方向光:

不正常渲染:



A:Chunk 模式下做了一下测试,大概结论是在聚光灯的情况下,重叠的部分有三个颜色叠加(一个 Base Pass,两个 Add Pass);没有重叠的部分有两个颜色叠加(一个 Base Pass,一个 Add Pass)。其中的 Base Pass 是由强度为 0 的平行光及环境光等组成,Add Pass 是聚光灯。重叠部分多了一个 Add Pass 的颜色,所以看起来就会 “不和谐”。

先来说一下为什么会有重叠部分。假设一张 128x128 的纹理,按照默认 100Pixels Per Unit 的设置来算,这个纹理的长度为 1.28x1.28,但是 TileMap 的一个方格子是 1x1,所以把这个纹理往格子里放,两边就各多了 0.14,这样平铺的时候就会有重叠部分了。

从上图可以看到,越往聚光灯强度高的地方,重叠的颜色看起来越 “异常”,因为刚好多出来一份聚光灯的颜色贡献。


上图为第一个 Base Pass,Keyword 为平行光和球谐环境光,Blend 模式为 SrcAlpha OneMinusSrcAlpha,这个纹理的 Alpha 为 1。这里的绘制效果相当于 Blend 模式为 One Zero,后画的颜色会完全覆盖先画的颜色。因此当只有一个平行光的时候,只有这一个 Pass,颜色非常和谐。

上图为第二个 Add Pass,Keyword 为探照灯,Blend 模式为 SrcAlpha One,效果相当于 Blend 模式为 One One,重叠的部分会把颜色往 Color Buffer 里面叠加两次。

以上是 Chunk 模式,对于 Individual 模式,发现了和 Chunk 模式不太一样的地方,渲染效果如下:

从上面的图可以看到,竖直方向上没有不和谐。仔细看了一下 FrameDebugger,发现渲染的顺序和想象的不一样。

前四个渲染分别是 1 个 Base,1 个 Base,1 个 Add,1 个 Add。第五个 Draw Call 的时候,为 Base Pass,Blend 模式变成了 One Zero,于是竖直方向上重叠的部分上之前的颜色被抛弃了。所以竖直方向最终效果并没有不和谐,而水平方向仍旧是重叠的部分多加了一次。

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


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


↙↙↙阅读原文可查看相关链接,并与作者交流