当前位置:首页|资讯

如何在游戏中正确旋转你的坤坤

作者:xxxNeedFor虚空藏xxx发布时间:2024-10-10


 “让物体旋转成面朝某个方向”。这个需求常见,又看似简单。但在Unity中直接使用Transform.forward设置,竟然会出问题!有的时候竟然会上下翻面!我勒个顶级游戏引擎欸!

   现在,让我们通过自己处理这个问题,看看这里面到底出了什么问题。

  “理解提问就是找出答案”

    我们的坤坤和我们一样,是站立于地面上的生物。也就是说,让“让物体旋转成面朝某个方向”并不是一个通用的3D空间问题,而是一个前提条件非常多的3D空间的2D问题。


而且,经过咱的慧眼发现,不论是坤坤还是其他外来模型资源,不能保证轴向,旋转和(游戏引擎)世界的轴向,旋转一致:

所以咱就可以看出来了,不能全帅锅给Unity,这不完全是个数学问题。

所以我们需要添加额外信息,保证一切正常(使朝向正确对应数学方向):

Type:设置旋转轴(这也是方便处理了,复杂情况要先把坐标系转成比较舒服的local系,才能直接通过euler.y控制坤坤的朝向)

Initial Rot:我发现只有初始旋转为(0,180,0),坤坤才能正确面向我们的“零方向”,也就是XZ平面的X轴

Add With CCW:正常来说,按数学约定俗成,x轴为0,逆时针旋转角度增加。但是我们的坤坤逆时针旋转euler.y在减小的,所以为false(再次声明,这也是方便处理了,具体原因是模型系-世界系-鸡头方向不能保证一致,由于涉及到不同引擎,不同DCC软件的坐标系设置,和创作者的规范习惯,所以你看到了,没办法只能具体问题具体处理)


全部处理完之后,我们可以写出euler.y和数学角度deg的对应转换了:

“唉”,你该说,“这下咱坤坤能正常摆动了吧?”

乍一看好像可以:

但如果你实际使用这个“起始角”turn_startDeg和“目标角”turn_targetDeg后,会发现有一些“小瑕疵”。

第一,起始角是从euler.y来的,你不知道什么外部程序或者预设值会超过0-360,导致最后多转几圈。

第二,不能保证“最近旋转”,比如逆时针10度转到350度,其实应该是顺时针转到-10度是最快的。


为了解决这两点,首先将两个数值规范到0-360:

注意其中fmod是我们写的。如果你写过shader,要非常注意各语言的fmod关于负数的内在逻辑还不一定一样。我们需要的是负数和整数“连续且表现一致”的fmod,也就是说,比如fmod(10,360)=10,fmod(-10,360)=350。所以我们的fmod是这样的:

然后实现“最近旋转”,比较正反两种旋转,哪个abs大于180,就选另一种;而由于我们是lerp(起始角,目标角),所以这个操作就是对目标角适当地加一圈或减一圈:

最后,计算旋转时间时,也不要忘了处理负数:


这样我们的坤坤终于可以正常旋转,按最小角度左摆右摆,并且不用担心像Transform.forward那样倒吊了。



Copyright © 2024 aigcdaily.cn  北京智识时代科技有限公司  版权所有  京ICP备2023006237号-1