这是第148篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。
UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)
本期目录:
- 如何能避免动态字体Font Texture过大
- 场景Object对不同鼠标按键产生不同响应事件的实现方式
- UGUI中,在Canvas下改变某一UI是否会引起所有UI的重绘
- 播放Idle动画后角色产生位移
- 如何解决更新后场景中贴图会变黑的问题
UI
Q:Failed to update dynamic font (arial) texture; all the needed characters do not fit onto a single texture (max size 4096). Try using less text or a smaller font size.
项目中已经把字号控制在4个(16,22,26,30)了,理论上字号并不多,而且安卓上不会出现这种情况,一直查不清是什么问题。
A:我们使用FairyGUI,默认使用高清字体模式——编辑器下用设计分辨率设计字体大小,手机上根据实际分辨率进行了等比放大。例如设计分辨率用1280x720,手机分辨率1920x1080,字号就扩大了1.5倍。并且我们字体控件使用了自动适配控件大小模式,文本长度超过控件长度的话,会自动进行缩小字号来匹配,这样字号数量不可控的又多了起来。
我们目前的解决方案是:1.取消了高清字体模式;2.项目约定字号只用偶数,更改源码自动缩小的字号也只产生偶数。
感谢潘友成@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c3c51ee050b697811b11e7d
Input
Q:我在场景中实例化一物体,并且该物体会对鼠标指针的进入和进出做出响应(例如,指针指向物体时改变颜色,移出时恢复颜色)。同时,我还需要对鼠标的按键状态进行响应,左键和右键产生不同的操作。这种需求,除了在Object脚本的Update里做判断外,还有没有更效率的实现方式?
A:可以借助IpointerClickHandler接口:
https://docs.unity3d.com/ScriptReference/EventSystems.IPointerClickHandler.html
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
public class RightClick : MonoBehaviour, IPointerClickHandler
{
public UnityEvent leftClick;
public UnityEvent middleClick;
public UnityEvent rightClick;
public void OnPointerClick(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Left)
leftClick.Invoke ();
else if (eventData.button == PointerEventData.InputButton.Middle)
middleClick.Invoke ();
else if (eventData.button == PointerEventData.InputButton.Right)
rightClick.Invoke ();
}
}
将以上脚本挂在Object之上即可。
感谢hcj@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5b3e0d212a652c518d8d5300
UGUI
Q:请问如果一个Canvas下的某一个UI改变或者移动了,或者增减某个UI,会导致整个Canvas下所有元素的Rebuild吗?
我看网络上的大部分例子都是一个Canvas作为根节点,之后用Panel作为某一个界面的父节点,放在Canvas下。我有点疑惑,如果任何UI的改变都会引起Canvas的重构,重新计算Mesh之类的,那只有一个Canvas的界面布局方法,不是会导致很多无畏的消耗?
我想设计为:每一个功能界面都是以独立Canvas作为容器。那这个界面下的UI变化就不会影响到其他的Canvas,不会导致所有UI的重绘。这样的想法会有问题嘛?Canvas多了会有额外性能消耗吗?(DrawCall这个我已经考虑过了,可以接受)
还有其它可行的设计方案吗?
A1:首先,推荐UWA博客里面有一篇关于UGUI优化的文章:
https://blog.uwa4d.com/archives/QA_UGUI-1.html其次,UI元素的位置,颜色,大小变化,都会导致Canvas的更新或者重建,因此要避免重建,要尽可能把频繁变化的UI元素从复杂的Canvas中分离出来,以此将动态UI元素的变化所引起的网格更新或重建所涉及到的范围变小,减轻Canvas更新和重建带来的性能开销。
再次,通常情况下,如果整个游戏只有一个Canvas,确实会带来很多无谓的性能消耗。
最后,每一个功能界面以独立的小Canvas作为容器存在,我们在量级很小(整个游戏不超过10个界面)的产品里面用过。能否通用所有项目情况,我认为需要具体情况具体分析。
感谢张锐@UWA问答社区提供了回答
A2:推一波自己文章,记录了相关的概念,应该能帮助你有个清晰的认识:
https://www.jianshu.com/p/5c44eb589751关于Canvas的划分,首先每个功能肯定有一个独立的Canvas,在做显隐控制的时候会方便。然后对于界面复杂的功能,要酌情拆分出子Canvas,拆分条件可以参考UWA文章,基本是动静分离为主。
UGUI中,Canvas少不一定DrawCall少,所以这方面可以不必太过在意。而且当界面臃肿的时候,重建的消耗是远高于多几个DrawCall的。
感谢Walker@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c5125b97692f15c777a5558
动画
Q:我希望角色模型在播放Idle动画时位置保持在原地,当打开Apply Root Motion时,角色会产生微小的位移和旋转,关闭Apply Root Motion时,角色位置虽然能够保持在原地,但角色的动画就会很奇怪,两只脚不再保持跟地面接触,而是像漂浮在空中一样摆动两腿。
A:如果是Humanoid模式的话,可以试试这边的Bake Into Pose的选项:
如果是Generic的话,可以先看看这里的设置是不是None:
如果是None也有问题,再把动画压缩关了试试,看看是不是精度的问题:
该回答由UWA提供,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c5fdfc32b3589332f1a4951
纹理
Q:从2017.4.17f1更新到2017.4.18f1(19f1和20f1也会有这个问题)后,再打版本运行到Android 4后,场景中某些贴图会变成黑色,某些贴图不会。
出问题和不出问题的贴图,都是ETC1格式,Diffuse材质;
出现问题的设备有:红米Note1(4.4.4)、红米2(4.4.4)、三星 G3608(4.4.4)、三星Galaxy S3(4.3)、Oppo1107(4.4.4);
UWA的红米2(5.1.1)没有发现这类问题。
补充截图如下:
@deviljz 提到在2018.2 上遇到过一个变黑的Bug,满足以下4个条件贴图会变黑色:
1、长宽比不是1:1
2、开Mipmap
3、ETC压缩
4、在安卓4.4上
感觉应该和我们遇到的问题一样,请问这种有什么解决办法,除了降低Unity版本。
A:解决方法:只要让2、3条件有1个不满足就行了。
比如写个OnPreprocessTexture方法,判断长宽比不是1:1的情况下强制指定压缩方式是ETC2,不用ETC压缩。
感谢deviljz@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c61184763826a332ad994da
今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。
官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:793972859(原群已满员)
封面图来源:Unreal Landscape
https://lab.uwa4d.com/lab/5b85803f02004fb659765ee1