技术分享连载(八十七)

技术分享连载(八十七)

本期聚集了这些话题:美术资源导入管理、通过Camera Layer Mask优化UGUI、烘焙效果出错...
UWA一下,你就知道~


我们将从日常技术交流中精选若干个开发相关的问题,建议阅读时间15分钟,认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。

UWA QQ群:793972859
UWA 问答社区:answer.uwa4d.com


加载

Q1:我们每次大批量地合入美术资源时,经常会出现构建出来的版本出现材质引用丢失、Animator Controller引用错误、贴图引用错误等资源引用错误的问题,美术资源在本地是正确的,其他人机器上Editor看也是正确的,构建机Editor看也是正确的,但构建出来的Bundle是坏的。有时删除Bundle再编会解决,有时则不行,目前遇到这种情况,只能让程序同事在构建机上删Meta重新做一次Prefab,费时费力而且不规范。

想问问这是Unity的Bug吗?大家有没有规避或者优化的方法?在管理美术资源合入的时候有没有更好的流程,我们目前使用Perforce管理Unity工程,要求美术显式上传资源配套的Meta文件。

我根据我们项目遇到过的问题猜测下,我觉得项目资源导入某个地方有问题的可能性更大些,题主是否可能存在以下情况:

1、是否使用代码混淆。在Prefab 上挂的脚本忘记添加到排除混淆的列表,导致序列化的字段被混淆,打完Bundle后的Prefab资源加载时候,挂接的脚本出现引用错误;

2、资源导入都重载过OnPostProcess并处理了资源设置,这一步是否修改了什么不合理的地方,比如破坏了引用关系;

3、打包AssetBundle时,在构建Bundle 之前有没有使用文件操作API(不是 Unity 的AssetDatabase的API)来直接修改了某个文件夹或者其他会破坏引用关系的行为,然后构建Bundle,完成后恢复文件夹名字(或者恢复资源原始状态),这样丢失引用关系的几率很大;

4、有没有可能发布机器上,看着正常,但是Perforce里面已经存在一堆已修改的Meta文件;这种问题常出现于美术本地有两个A1,A2个相同资源在不同文件夹,A1受版本控制,但是由于某种操作,本地临时资源A2使用了原本A1的Guid,原本正确的 A1 被迫使用了不正确的新生成Guid(相当于两人交换),然后上传了A1的Meta,结果发布机器的下来的A1 Meta就会跟别人丢失引用,或者更新下来本地重新分配了新的Guid;美术策划最容易犯这个错误;

5、我们是Unity 5.3.8p2,上周遇到一个疑似bug,美术多上传了一组相同的资源,我们更新下来都会重新生成Guid,但是很多挂起的Meta在Unity里重新导入后,在版本控制里神奇地消失了,但修改还在;

6、如果都不是,只能尝试最小排除法了,删除项目绝大部分资源,一点点增加,然后打包,重现,排除原因;不行的话然后删除代码,一点点添加,打包,重现...有时候笨办法也是最容易接近真相的。

该问题来自UWA问答社区,感谢Yaukey提供了回答,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a0e8184e8a3d9357ce19473


UI

Q2:我在UGUI 使用一个UIRoot,类型使用Screen Space - Camera,使用摄像机的 Culling Mask, 如果UIRoot可视,下面的UI子物体设置不可视Layer,是不是不会被裁掉?有没有什么解决办法吗?

UGUI的网格合并是以Canvas为单位的,所以只能改Canvas的Layer才有效。如果只是个别UI元素要快速隐藏和显示,可以考虑用Scale为0来做,Scale为0时UI的顶点信息会被清空,所以隐藏时就不会参与网格重建了。

该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a10004eabfda3486d8d6811


渲染

Q3:我在Unity 5.5.4版本下烘焙建筑物(Windows平台下),中间楼层出现黑块,请问什么原因导致呢?,我只用了一个方向灯,但烘焙的时候环境色用了白色,如下图:

上传了工程例子供参考:testLightmap.unitypackage
请输入图片描述

我找到了另一种方式,修改LightmapParameters的,新建一个LightmapParameters,修改里面的Backface,Tolerance改为很小的值就行,我的是0.2,如图:
请输入图片描述

该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a07e839e923796076c9b5db


UI

Q4:NGUI(3.11.1)、Unity5.6.4版本下出现两个Panel控件后,通过RenderQ控制特效层级失效的情况,具体操作如下:

在一个UIroot下面有两个Panel,Panel A 下面有个Effect 通过脚本particleLayerControl.cs 控制Render Q 来解决在UI上特效的层级问题,当有另一个Panel B(一个空的Panel,它的layer < Panel A的Layer),就会发生特效永远最先绘制的问题。在附件中有个测试场景:

当没有Panel B的时候是正常的,我通过FrameDebug调试发现,当Panel B 被启用后,特效是永远最先绘制的,但通过读取Render Q 的值,特效要大于UI,不知道是为什么。
上传了例子工程供参考:testRenderQ.unitypackage

测了下例子确实可以复现。这是因为较新版本的NGUI,UI Panel也加入了SortingOrder的概念,在开启Panel B时,Panel A的SortingOrder从0变为1(Panel B的Depth比Panel A的Depth小),这个时候粒子的SortingOrder还是0,所以就被覆盖掉了。如果把Panel B禁用了,或者把PanelB的Depth改到40(大于Panel A的Depth)都可以使得粒子出现。
所以需要在particleLayerControl中加上SortingOrder的处理,即保持粒子的SortingOrder和所在的UI Panel的SortingOrder始终是相同的。

该问题来自UWA问答社区,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a0a50113a88251e734e5628


Unreal 4 渲染

Q5:我想问下Unreal 4的 Movable光源的Shadow Map Cache问题,它的具体更新策略是什么样的呢?如何处理动态物体与静态物体的关系?需不需要对Shadow Map进行Cascade?

我同时也参考了Cry Engine的文档:
http://docs.cryengine.com/display/SDKDOC2/Cached+Shadows

同时如果想移植到Unity,可行吗?或者我想解决大面积实时阴影的问题(光源方向会变化,大部分物体是动态物体 但是频率都不高)有什么解决方案吗?我可以在光源Space下预烘焙数据来达到光源方向变化,用一张Shadow Map的可能性吗?类似 Directional Light Map那种建立空间的?

Unreal 4的这个Movable Light的Shadow Map Cache只能给Static、Stationary物体用,因此我觉得其实是想给Movable光照下的Static物体阴影计算做个优化。但是Mobile端没必要用Movable,Stationary就好,Static物体的阴影是预计算的。

Unreal 4的动态物体在计算阴影的时候会计算两次,一次是从静态场景投射到动态物体,一次是动态物体投射到静态场景。在计算静态场景投射到动态物体阴影时,引擎会缓存一张静态场景的Shadow Map,用于计算投射到动态物体上的阴影。因此,对于动态物体也能接收到来自静态场景的精确阴影遮挡,但是这个方式比较耗时,而且mobile也不支持。

Unreal 4也提供了类似Unity的对静态场景投射到动态物体阴影近似解决方案,也是将shadow的预计算结果存储到带有间接光信息(也是SH)的点云(在Unity中就是light probe)中,然后根据动态物体的位置从点云插值出阴影遮挡,但是这种方式只能得到物体整体明暗度的变化,无法计算精确阴影。Unreal 4是推荐mobile上使用后面一种方法的。

需要补充一下的是,Unity解决动态物体接受静态物体烘焙阴影也是采用Light Probe的。题主说是动态光源,动态物体,最好还是实时阴影计算。如果是采用Shadow Map Cache的方案做优化,可能得看具体场景和需求。预计算烘焙多个Shadow Map的方案可能需要考虑两个因素,一是光源变化,二是动态物体变化。如果动态物体和光源变化频率都不高,那么可以尝试对它们采样预计算好Shadow Map。但是这样带来的Shadow Map占用空间和内存开销我们也不清楚,可能得尝试一下才知道。

以上回答由UWA提供。

关于Unreal 4的实现,楼上已经说得很详细了,可以参考Unreal 4源码ShadowSetup.cpp/ShadowDepthRendering.cpp,搜索SDCM_StaticPrimitivesOnly相关的代码即可,我补充一下其他问题:
1、针对动静物体怎么处理
在手机上比较难完美,可以针对静物渲染一张SM,动态物件用planar shadow解决

2、Shadow Map Cascade
缓存的话,Shadow Map不能随时更新,如果镜头频繁大距离移动,cascade不能跟随镜头随时更新,过度可能会不自然,这需要根据项目特性权衡

3、能不能光源动,Shadow Map用同一张 看你怎么动,如果是模拟日光,轻微转角,那你只能放弃精确阴影计算,在判断某个空间点是否在阴影区时增加偏转角,相当于把阴影做平行四边形变形 如果想360度转,目前我也没有很好的思路能兼顾cache和平滑转动时的过度,毕竟物体的四面都长得不一样,不可能用一张shadow map做平行四边形变形而不穿帮。

感谢 招文勇提供了回答。

该问题来自UWA问答社区,,如您对该问题仍有疑问,可以转至社区进行进一步交流。
https://answer.uwa4d.com/question/5a0e6dc2e8a3d9357ce1946d


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

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:793972859(仅限技术交流)