厚积薄发Lua与C#之间的穿梭问题

Posted 侑虎科技

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了厚积薄发Lua与C#之间的穿梭问题相关的知识,希望对你有一定的参考价值。

这是第111篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间15分钟,认真读完必有收获。

UWA 问答社区:answer.uwa4d.com

脚本


Q:Lua与C#之间的调用频率是影响Lua性能很重要的因素,最近我们的项目也在分析这类问题。如何统计Lua与C#之间调用的次数呢?我感觉要注入的代码有点多,我们写了大量的warp代码,每个都添加有点不现实,而且warp代码都是自动生成的。大家有什么好建议吗?

我们项目用的是ToLua,Unity版本是5.6.1p1。


A1:Lua调用C#用debug.sethook。
云风有一个基于这个方法写的工具cloudwu/luaprofiler,不过不能直接拿来用,需要自己编库。

除了这个以外,直接在Lua里面挂上也是可以的,比较影响性能。
C#调用Lua看LuaFunction。

感谢凯奥斯@UWA问答社区提供了回答


A2:Lua和C#之间的调用次数统计的工具,只需要修改一下ToLua导出warp接口的地方就好了,重新生成一次代码,加上宏或者条件编译的控制,就可以很方便地做到即可以在编辑器模式下做次数统计,又可以不影响发布到设备上的过程。

生成的代码可以自己添加tag,用于统计,比如我们的一个调用代码:

【厚积薄发】Lua与C#之间的穿梭问题

UWA在UWA Day上展示的过程就更简单,直接封装成函数,通过[Conditional(“XXX”)]来控制就好了。


如果要统计C#反向调用Lua的地方,LuaFunction的几个Call函数是一个切入点。

感谢贾伟昊@UWA问答社区提供了回答


迎大家转至社区进行进一步交流:

https://answer.uwa4d.com/question/5af3b9b46b104d27ac3aace5

动画


Q:为了动画重用减少资源重复的问题,我们采用人性形动画格式来制作。因为有第一人称,手掌手腕是处于特写状态下的,所以任何瑕疵都会暴露无遗。为了避免手腕扭曲变形的瑕疵,我们添加了附加骨骼来解决问题,骨骼的位置和结构关系如下图:

【厚积薄发】Lua与C#之间的穿梭问题


Unity中没有添加附加骨骼的手腕旋转效果:

【厚积薄发】Lua与C#之间的穿梭问题


Unity中添加了前臂附加骨骼的手腕旋转效果
问题1:手腕和手臂交界处有错位现象

【厚积薄发】Lua与C#之间的穿梭问题


Max中添加了前臂附加骨骼的手腕旋转效果(可以看出手腕扭曲完美解决,但是在Unity中效果不理想)

【厚积薄发】Lua与C#之间的穿梭问题


问题2:人形动画格式大拇指的动画就是没办法还原,总是敲着的,我们检查过骨骼匹配问题,如下图都是正常的,就是大拇指没办法弯曲。

【厚积薄发】Lua与C#之间的穿梭问题


【厚积薄发】Lua与C#之间的穿梭问题


A:Unity的人形骨骼这里在使用的时候有不少小坑,而官方文档很多地方写得很隐晦,我们项目在用人形骨骼,在用Retargeting的时候也是各种动作有小问题。

先说一下我们自己得出的一些结论吧:


1)角色自己的动画,使用自己的Avatar,人形骨骼应该是可以做到和Max以及Generic的方式的动画完全一样的效果;


2)如果是别的骨骼,有体型上的差异,比如身高、肩宽等,经过Retargeting的效果之后,可以做到整体效果是正确的,但是因为累积误差的原因,距离根骨骼比较远的骨骼,比如脚、手指等位置,会有微小的差异,比如脚不够贴地、idle动作脚部有微小的抖动现象等等。


Retargeting的原理我之前写过一篇文章,有兴趣可以看看。这里补充一些后来我们自己在使用的时候发现的点。Unity中有几个文件,他们记录的信息分别有:


1)Avatar文件,就是所谓的骨骼文件,这里记录了用于Retargeting的基本的T-pos信息,Unity中定义的是一个大T的姿势,而Max里常用的可能是一个小T姿势,所以这里要做一些调整,细节后面来说;


2)动画文件,记录动画差异信息。导入的动画文件在使用人形骨骼的情况下会需要指认Avtar的引用到所对应的文件上,如果Avatar有修改,动画文件需要进行Update操作,这个过程是重新计算差异的过程。我们观察到,这个动画文件的内容,和导入动画文件的Max文件里的T-pos姿势有很强的相关性。


如果你看了之前的文章,那这里就比较好理解了。我们有两套骨架,A、B,需要把B的动作应用到A上,那需要四个数据:


  • A的T-pos信息;

  • B的T-pos信息;

  • B的动画信息;

  • A的动画信息 = B的动画信息 - B的T-pos信息 + A的T-pos信息。


所以前面说的动画文件里的信息,其实应当理解为B的动画文件和B的T-pos的差异。(这里说得有点绕,先埋个坑吧,等我有时间了详细整一篇博客好了。)


所以我们项目给到美术的建议是:导出Avatar的T-pos和导出动画的Max文件里的T-pos信息要一致,这样才能做到动作尽量的还原。(所以你可以测试下,使用同一个Max文件导出的动画和Avatar,在Unity里应当和Max里是完全一致的才对。)


说了半天原理,也是说上述的一些问题可能需要题主自己来根据原理推测并解决。
当然还是要说下我对于这两个问题的想法。


第一个手腕扭曲的问题,说实话我貌似遇到过,但是时间有点久远,具体的细节不太清楚了,建议题主查看下几个方向:


  • 是否非人形骨骼也有这个问题?

  • 是否可能是蒙皮的问题,或者通过修改蒙皮来解决?

  • 是否是人形骨骼Avatar里的手腕的骨骼映射关系存在问题,通过调整Avatar的姿势是否可能缓解这个问题?


第二个手指不动的问题,可能需要确认下Avatar里的姿势手指是否和预期不一样,这种情况可以通过给动作中的手指一个很夸张的姿势来查看,如果真的是完全没有动作的话,查看下动作中是否mask的设置有遗漏?


动作这块是需要程序和动作美术一起不断测试,才能找到一个好的平衡点。我自己是Max不够熟悉,所以看问题的时候还要拉着美术一起。


感谢贾伟昊@UWA问答社区提供了回答,欢迎大家转至社区进行进一步交流:

https://answer.uwa4d.com/question/5af15a3b6b104d27ac3aacad

动画


Q:动画片段的数量对性能开销是否有影响?若有,对同一个动画片段,不同层级的多处复用是否也是有影响?(动画控制器游戏过程中没有激活和隐藏操作,不清楚动画片段数据的采样和读取消耗为何会偏高)


A1:动画说白了就是变换而已,平移、旋转和缩放。每一帧将变换矩阵乘到各个顶点上,而这部分是纯CPU计算。

那么与性能开销相关的就是:顶点数量、骨骼数量、层的数量。

另外一个就是BoneWeight了,weight(n)的非零个数越多,每一帧顶点的变换计算也就越多。

所以可以优化的点:
1)减面
2)减少骨骼
3)精简层
4)减少骨骼blend数量
另外对于动画所占内存的优化,可以参考文章:

感谢凯奥斯@UWA问答社区提供了回答


UWA:除了process animation, 动画片段数量也会对animatorcontorller的维护带来开销(反映在writejob上):"when using the Animator, all the properties of all the clips currently connected are written, whether the clips are playing or not. "


迎大家转至社区进行进一步交流:

https://answer.uwa4d.com/question/5af1391e6b104d27ac3aac9c

粒子系统


Q:当场景中有大量的环境粒子系统,针对粒子系统做过裁剪优化,请问粒子系统在远离相机后怎么正确的进行休眠,把粒子系统进行stop就行了吗?会对渲染或CPU还有没有多余的开销?还是只能把粒子系统根节点的gameobject的active设置为False?


UWA:建议通过Active和Deactive来进行控制,未Deactive的Particle System一样会参与计算,比如渲染模块中的Culling等等。同时,Active/Deactive对于粒子系统对于粒子系统的处理一般都不耗时。


该回答由UWA提供,欢迎大家转至社区进行进一步交流:

https://answer.uwa4d.com/question/5af248ba6b104d27ac3aacc5

代码


Q:我在使用Deep Profile查找代码性能时,发现一个列表查找每次Find()都会产生2.5KB GC Alloc,然后我改变了一下写法,不用Find(),直接for循环遍历,发现GC Alloc没了,耗时几乎一样。然后我去查找了Find()的IL,也没觉得哪里会产生GC,请大家指教。


A:【厚积薄发】Lua与C#之间的穿梭问题

【厚积薄发】Lua与C#之间的穿梭问题

【厚积薄发】Lua与C#之间的穿梭问题


我猜测题主的代码里是类似下面的这种逻辑:在一个循环里,多次执行了Find操作,Find的参数(闭包函数)使用了每次循环都会变化的non-local变量,因此产生了较多的GC。这种方式产生GC的原因是,每次循环会new一个委托对象。


感谢Walker@UWA问答社区提供了回答,大家可转至社区进行进一步交流:

https://answer.uwa4d.com/question/5af6fcac6b104d27ac3aad00


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

官网:www.uwa4d.com

官方技术博客:blog.uwa4d.com

官方问答社区:answer.uwa4d.com



近期精彩回顾

 


以上是关于厚积薄发Lua与C#之间的穿梭问题的主要内容,如果未能解决你的问题,请参考以下文章

厚积薄发ToLua的释放时机

补发:论厚积与薄发

三年挖矿 厚积薄发

记录点滴,厚积薄发!

厚积薄发LuaJIT性能热点函数优化

厚积薄发大世界场景优化和加载策略