1)FairyGUI图标文字合批失败的原因
2)为什么Cubemap的内存占用超高
3)如何找到网格某个切面的中心点
4)为什么SafeZone在倒屏后方向相反
这是第428篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术知识点,助力大家更全面地掌握和学习。
UI
Q1:项目现在使用的是FairyGUI,界面中会有一排类似下图的比较常见的组合按钮(图+特效+文字)。
在FrameDebugger中注意到这部分的DrawCall情况有点惨;老项目用UGUI+TMP作类似的UI应该是没有问题都能合的。父节点FairyBatching是勾了的,图集是合好了的,图和图、文字和文字之间应该也没有互相遮挡覆盖;考虑到可能是特效穿插的问题,所以运行调试时直接把特效的节点删掉了,还是不行。请问还有什么思路?
A:遇到过类似的问题。首先FairyGUI的结构在导出后应该就是固定的了,有可能你运行时做了修改删掉改掉某些东西,但原来的区域规格和UI元素仍然占位。所以这里删特效、对TextField覆盖面积的调试检查,可能都得请UI同学帮忙,回到FairyGUI编辑器阶段处理和检查,再重新导出看效果。
Q2:操作了下,确实有变化。但现在又有两个新问题:
1. 确实导出前就把特效移除有效果,但图和文字中夹着特效是表现需要,最终不大可能删,这个是不是就没什么办法了?
2. 就算移除了特效,还是发现只有图和图之间合了,文字之间仍然不合。而且这次是确认了TextField之间也没有重叠。这时候看FrameDebugger合批失败原因变成了超过300个顶点不能动态合批。请问这个怎么解决呢?
A:第一个确实想不到什么办法了。第二个就像FrameDebugger写的一样,你若是用了Shadow、Outline这种效果,文字的顶点就会成倍上升,再加上你字一多,就会超了。不过如果你这些表现上都要用的话,也和特效一样没什么办法了。
感谢Faust@UWA问答社区提供了回答
Memory
Q:在MemoryProfiler里发现Graphics分类下面Cubemap的内存占用有40多MB,比我们项目用的网格都多,这个量正常吗?
A:确实高了,尤其移动端游戏很少有必要用这么多。可以看下是不是有些Cubemap单个就占好几MB。一个Cubemap本质是6张Texture 2D,所以一个10241024、ASTC44格式的资源就占6MB内存了。但其实我测下来其规格对表现的影响很微妙,像我们项目里有些物体上把Cubemap改到128128、ASTC88看上去都没什么区别,但内存就小到可以忽视。最终也是说服美术在低分档上用这版了。
感谢Faust@UWA问答社区提供了回答
Script
Q:我想要找到一个网格中某个切面的中心点,有什么实现的思路吗?
A:提供一种追踪的方式,大致思路是:
- 通过Get Component Bounds得到网格包围球的半径,乘二以保证追踪起点足够远,得到追踪的半径(Float)。
- 在For Loop中配合Rotate Vector Around Aixs和追踪半径来得到足够多的追踪点(Float→Vector),它们是LineTrace的起点。
- 再找到追踪的终点,就可开始Line Trace(起点和终点还要加上Actor自身的Location,相当于Local→World)。
- 返回的Out Hit中拿到Location便可加到一个新的Vector Array中(这个要是局部变量,这样每帧得到的都是新的)。
- 在For Loop的Completed阶段用Draw Debug String来显示内容(也可以别的类型),输出一个白色的x,位置为Get Vector Array Average,即该切面的中心点。
蓝图如下:
进阶版:若希望这个切面不只是水平面,还可以换成其它角度。加一个Plane进来,蓝图如下这样改,旋转Plane即可调整切面的角度(理论上还可以继续优化,因为没把Plane的位移算进去)。
蓝图如下:
该回答由UWA提供
Script
Q:在左右横屏切换之后,原本设置的安全区位置出现了错位,请问是什么原因呢?
A:该现象确认为UE的Bug,已在5.2中解决,可参考:
Unreal Engine Issues and Bug Tracker (UE-170632)
之前版本不修改源码解决该问题的方法:在屏幕旋转时,手动触发安全区更新。
实现的关键点包括:
- 安全区更新。可以通过全局代理触发:
- 获取屏幕旋转事件。屏幕旋转时会触发代理广播,因此可以将相应函数绑定至该代理:
另外,对于移动平台,可以直接使用PlatfromGameInstance提供的委托,在蓝图中绑定相应事件:
自己的GI类中可以做类似的实现:
基于以上关键点,项目组可根据自身项目需求进行实现。
实现参考:1. 创建PlaftormGameInstance,并替换为项目使用的GI。
2. 创建UBlueprintFunctionLibrary类,并在其中实现函数,该函数用来触发FCoreDelegates::OnSafeFrameChangedEvent.Broadcast()。
3. 在UI中,实现以下蓝图,注意其中对函数库中更新函数的调用需要延迟调用。
针对该Bug的源码变化:
5.2版本源码中的修改:
5.2版本之前:
该回答由UWA提供
封面图来源于网络
今天的分享就到这里。生有涯而知无涯,在漫漫的开发周期中,我们遇到的问题只是冰山一角,UWA社区愿伴你同行,一起探索分享。欢迎更多的开发者加入UWA社区。
UWA官网:www.uwa4d.com
UWA社区:community.uwa4d.com
UWA学堂:edu.uwa4d.com