头图

1)FairyGUI图标文字合批失败的原因
2)为什么Cubemap的内存占用超高
3)如何找到网格某个切面的中心点
4)为什么SafeZone在倒屏后方向相反


这是第428篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术知识点,助力大家更全面地掌握和学习。

UWA社区主页:community.uwa4d.com
UWA QQ群:793972859

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()。

  1. 在UI中,实现以下蓝图,注意其中对函数库中更新函数的调用需要延迟调用。

针对该Bug的源码变化:
5.2版本源码中的修改:

5.2版本之前:

该回答由UWA提供

封面图来源于网络


今天的分享就到这里。生有涯而知无涯,在漫漫的开发周期中,我们遇到的问题只是冰山一角,UWA社区愿伴你同行,一起探索分享。欢迎更多的开发者加入UWA社区。

UWA官网:www.uwa4d.com
UWA社区:community.uwa4d.com
UWA学堂:edu.uwa4d.com
官方技术QQ群:793972859


侑虎科技
65 声望23 粉丝

UWA官网:[链接]