内容简介:这是第140篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。UWA 问答社区:answer.uwa4d.comUWA QQ群2:793972859(原群已满员)
这是第140篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。
UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)
本期目录:
- 动画骨骼节点批处理
- 粒子系统崩溃
- 自定义Shader在iOS上出现异常
- Editor里可以达到100帧,真机上FPS一直低于30帧
- 多语言下Text组件大小和文本长度的适配
动画
Q:动画系统中开启Optimize GameObject选项后,不必要的骨骼会消失,我们在骨骼下面挂了很多特效挂点,也清楚可以通过 Extra Transforms to Expose暴露出挂点,但是每个模型去手选暴露太过麻烦,能否有批量处理的方法呢?
A1:这个可以通过Asset Postprocessor在导入的时候对模型进行遍历,将符合指定前缀的节点路径加入到Model Importer的Extra Exposed Transform Paths属性里,之后再调用Optimize Transform Hierarchy去实现优化节点的效果,不知道我有没有理解错。
感谢Enak@UWA问答社区提供了回答
UWA:补充楼上,如果是已知确定的节点名字,可以直接赋值,总之都是用OnPreprocessModel,具体规则自己项目组里约定好就好了。
public static string[] NodeNames = new string[] { "node_head", "node_arm", "node_leg", }; void OnPreprocessModel() { ModelImporter importer = assetImporter as ModelImporter; importer.optimizeGameObjects = true; //若实际骨骼中没有以下节点,可能会报错,但不影响使用 importer.extraExposedTransformPaths = EWEquipmentsBase.nodeNames; }
A3:楼上两个回答都有效,但还有一个更简单的办法。
先说一下Extra Transforms to Expose的大概原理(不一定都对),观察UnityEditor.dll相关实现可知:
1)开发者修改ExtraTransformstoExpose后,Unity会将信息保存在fbx的meta文件的extraExposedTransformPaths属性中。
2)在Unity根据fbx文件生成Prefab时,会依据meta文件中的extraExposedTransformPaths每一个String创建一个对应名字的空GameObject,并且不需考虑父子关系。
3)运行时,(推测)Prefab被Instantiate后,其Animator组件Awake时触发了Animator.Rebind方法,该方法会遍历Transform的子节点,将子节点的name和Avatar中骨骼信息对比,随后自动绑定节点。
这也是Optimized之后Animator组件上必须有Avatar的原因(非Optimized的GameObject可以将Animator组件的Avatar引用置空),想进一步研究Avatar可以将Inspector改为Debug模式查看。
基于以上分析,我们可以模仿这一过程,直接在Optimized之后的Prefab下面创建空的GameObject,随后将该空GameObject的名字改成约定好的骨骼挂点名字,这样就实现了和ExtraExposedTransformPaths相同的功能。
更进一步,我们可以利用Animator.Rebind方法实现运行时动态添加删除挂点的功能。这样做的好处是一来特效和策划同学无需反复修改Prefab(当然也可以离线制作好);二是无需为Prefab绑定所有的挂点,只需创建配置表里实际用到的挂点,甚至可以把挂点GameObject放入对象池回收利用,角色比较多且默认挂点比较多的情况下可以起到优化内存的作用。缺点就是Animator.Rebind耗时比较大,可以考虑随着Instantiate调用。
动态绑定挂点示例:
1private static readonly string[] s_BindPoints = new string[] 2{ 3 "node_head", 4 "node_arm", 5 "node_leg", 6}; 7 8private Animator m_Animator = null; 9private void Awake() 10{ 11 m_Animator = GetComponent<Animator>(); 12 Assert.IsNotNull(m_Animator); 13 foreach (var bindPoint in s_BindPoints) 14 { 15 GameObject bindPointObj = new GameObject(bindPoint); 16 bindPointObj.layer = gameObject.layer; 17 bindPointObj.transform.SetParent(transform); 18 } 19 m_Animator.Rebind(); // important! 20}
感谢张迪@UWA问答社区分享了该经验
该问答来自UWA问答社区,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c0a256a28c4e32cba3192eb崩溃
Q:求助一个低概率随机崩溃问题,下面是崩溃的堆栈信息,我在网上搜索了下 “Abort message: ‘* Assertion at mini-arm.c:2634, condition `pdata.found == 1’ not met” 有人提到是与DLL相关,Android平台上应该是与本地的native code代码相关(当前项目使用了liblua53.so和其他 lua 相关的.so库),看了下mini-arm.c的源码,的确是在处理 mono_code_manager 相关一些东西,不知道有哪位大神遇见过并解决了的,请不吝赐教!
题主:上周我们项目进行了7天外网小规模(2000左右玩家)测试,在这期间面对的崩溃问题的处理过程和问题原因,仍旧比较深刻。
之前,崩溃在libmono.so “Abort message: Assertion at mini-arm.c:2634, condition `pdata.found == 1’ not met” 的这个低概率随机崩溃问题一直困扰着我,主要是这个问题崩溃在mono,崩溃的栈信息完全与libunity.so,libmain.so无关,更别说基于Unity的逻辑层代码,面对我们的对外测试11月30号时间临近,我在28号的时候对mono进行一次简单的处理:将mono代码mini-arm.c:2634 中的断言 g_assert (pdata.found == 1); 注释掉,换成了普通的错误信息输出,编译后直接提交到项目工程中,毕竟这个改动算是无害处理,然后开始去优化项目中卡顿点去了,也没有继续跟踪这个改动,因为当时想到是小概率事件。
11月29号提交给发行版本后,晚上发行反馈说,感觉这个版本的崩溃率有点高,但说没有实际统计过,得到这个反馈后,我也没有特别在意,继续处理其他问题去了(真后悔当时没有去看bugly)
11月30号中午正式开测,到下午4-5点后,部分同事反馈告诉我说,崩溃率有点高,平时测试都不会闪退,今天闪退2-3次了…其中一个同事告诉我说,挂机15分钟内必崩溃…当时听到这个问题后心里一紧,赶紧去看了下bugly,发现崩溃率到了7.x%,远高于平时我们测试2.x%的统计,我再仔细一看,都集中在各种粒子系统崩溃中:
看到这些崩溃后,回忆了下最近两天的优化,在优化卡顿的问题中,当时对粒子系统组件 ParticleSystem 进行了本地引用缓存,不需要每次播放技能特效时都进行一次GetGetComponentsInChildren(true),同时对技能特效粒子系统停止时调用stop()修改为pause()(技能特效播放完后就回收到pool中,所以调用pause()不会有残留,此时不需要释放数据,在切换场景时真正释放特效数据),这时我从崩溃栈看到信息首先想到的修改应该是stop()修改pause造成的崩溃,我让程序同学帮我在iOS上挂机复现这个问题,果然连续2次挂机打怪都复现了,8-12分钟内必崩,崩溃栈和bugly上统计一样。
这时我立刻开始在iOS上直接修改编译测试,将pause()还原为stop(),继续测试… 意外的是问题依然存在,15分钟内挂机必崩溃闪退,然后又思考了下,stop()只是停止当前粒子更新和粒子发射,但数据没有清,然后继续修改代码:stop()调用后,立刻调用clear()再次测试,郁闷的是仍旧15分钟内挂机必闪退崩溃…再仔细看了下播放特效的代码上下逻辑处理,找不出问题,平时的崩溃率绝对没有这么高,仔细回想了下,这2天还剩余唯一的改动就是添加了对 ParticleSystem本地引用缓存,于是直接在iOS上修改为播放完后立刻本地引用置空,编译,更新到真机测试…一直测试了30多分钟,40多分钟都没有再闪退崩溃,哪怕改回pause()调用,也没有再崩溃了…这个测试结果有点让我意外,当时没有细想,立刻正式修改热更新到外网…果然外网的崩溃率第二天的记录再下降,但仍然存在,但我心里已经知道问题了,因为还剩余UI特效播放未处理(技能特效和UI特效我们是划分开的,技能有高低配设置,初始化解析不同),同样修改UI特效之后,闪退崩溃几率继续下降,一直降低到1-2%,剩余的崩溃仍旧是UI粒子系统相关的,主要是部分UI功能业务层未主动调用回收特效的接口导致。
这次对外测试结束后,我再回头看看崩溃信息,意外地发现让我最头痛的mono崩溃数据终止在28号,也就是在我28号修改mono代码之后就再也没有报崩溃在libmono.so “Abort message: ‘* Assertion at mini-arm.c:2634, condition `pdata.found == 1’ not met” 这个堆栈数据,回忆了下,以前低概率崩溃本质就是UI粒子系统导致的,有部分业务层逻辑未主动调用释放接口的,而mono-arm.c崩溃行 g_assert (pdata.found == 1) 断言阻断了继续向上层抛出堆栈信息…
我们的Unity版本是5.6.5P4,为什么缓存粒子系统组件不立刻释放会导致崩溃未知,可能是Unity的底层Bug,也可能真的是我们对粒子系统组件ParticleSystem逻辑上下调用有问题。
Shader
Q:自定义Shader在安卓手机上正常,在iOS上出现异常, 伴随一大堆的警告,而且资源会都变成黑色。
A1:第一行提示不完整,应该是说是没有顶点Shader;
第二行提示Pass都被移除了;
第三行提示没有可用的Subshaders或者Fallbacks;
总结起来,就是Shader是个空Shader,不可用。所以进行了替换,表现就是黑色,而不是材质丢失。
没用过ShaderForge,但是看过几眼美术同学从ShaderForge导出来的Shader,包含有关于平台的编译选项,大概是编译选项不对,要检查下ShaderForge编译选项设置。
感谢赵林@UWA问答社区提供了回答A2:首先切换到iOS平台,选择出错的Shader,有可能会显示Shader is not supported on this GPU,点击Compile and Show Code,应该会显示“Compile errors generating this shader.”
如果是这样的话,说明你用了Graphics API不支持的Feature。
感谢凯奥斯@UWA问答社区提供了回答帧率
Q:最近跑一个项目,在真机上无法超过30帧,看了耗时是只是十几毫秒。代码里没有对Application.targetframerate的限制。是什么原因呢?
可能是开了垂直同步限帧30帧那一档,垂直同步修改为60帧那一个,或者关闭垂直同步,用Application.targetframerate自己限帧。
UI
Q:多语言下,如何做Text组件大小和文本长度的适配?同一段文本,同一字体大小,不同语言下其长度(文字个数)和文字大小(像素宽高)不同,那么如何防止文本超出Text组件显示范围?如何保证视觉效果合理(文字不会太小也不会太大,位置不会太偏)?有哪些自动化的方案?
首先应该根据一种语言规划好文本框的大致大小,建议根据英语来规划,汉字有时候两个字,翻译成其他语言就是一长串。英语较为折中。
一种方式是固定好文本框大小,Bestfit,设置好最小和最大的字体,如果不拓展Bestfit,这种就有点粗暴。我们之前的项目就是这么粗暴;另一种方式是用ContentSizeFitter,可以计算出单个字符的大小,根据自己设定的最大最小值,通过扩展脚本可以动态的实现水平和垂直的扩展。
一般来说,肯定逃不掉特别极端的,所以再扩展个脚本处理这种非常特殊的。
今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。
官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:793972859(原群已满员)
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 骨骼数目和骨骼层级数目的美术规范
- 动态骨骼Dynamic Bone优化
- 纯 CSS 实现简单骨骼动画
- CSharpGL(50)使用Assimp加载骨骼动画
- 闲鱼Flutter互动引擎系列——骨骼动画篇
- 骨骼动画实现秘密!闲鱼 Flutter 互动引擎告诉你
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
图片转BASE64编码
在线图片转Base64编码工具
RGB HSV 转换
RGB HSV 互转工具