0x0
LookAt在RPG中是不可或缺的功能,对话系统中听者朝向说话者注视,主角路过npc,npc会朝向主角注视。目前有以下几种解决方法。
1.只转动头部
让我们来看看实际效果,以下是原神的某一个对话剧情,可以看出,只转动头部,效果差强人意,接近90度后,显得很不自然。另外这段动画中可以看到头部转动是匀速的,实际情况很少有匀速转动头部的情况,这个问题可以通过曲线缓动解决。
2.多骨骼IK
除了头部参与lookat之外,可以让颈部,胸骨等也参与lookat。
这里有2种实现。现在假设有3个骨骼共同参与lookat,分别是head->neck->spine
1.使用权重同时转动
所有joint同时转动。所有参与lookat的joint各自分配一个权重,比如头部权重是1,表示任何情况下都完全看向目标,spine胸骨权重0.3,表示不完全看向目标。FinalIK和unity内置的Animator.SetLookAtPosition采用的就是这种方法。
2.层级转动,上层关节到达限制角度后,移动下层关节。
从head开始,尝试转动看向目标,当达到最大限制角度但任然不能看向目标,则转动neck。如果head在最大角度限制内可以看向目标,则不需要转动neck。这个过程对neck,spine也一样适用。DOOM采用了这个算法。
Unity商城中Perfect Look At的插件也是使用该方法。插件的作者也很负责的在文档中说明了为何如此设计,和算法的思路。插件作者的博客地址
这里引用插件作者的文档:
想象以下你想用你的键盘写一些东西。当你按动按键,你主要用手指,而你的手臂和肘部很少移动。这体现了生物力学中的基本规则:如果你可以使用小肌肉干某事,你不会去使用大肌肉。使用更大的肌肉意味着消耗更多的能量,非必要的时候尽可能避免这么做。
现在想象你的正前方有一幅画。你可以仅移动你的双眼看它而不移动头部。现在把画朝你的左侧移动几厘米。你任然可以用你的双眼看到然而你感到你的眼部肌肉正在拉扯并感觉疲劳了。继续把画朝左移动,继续试着看画,你感到你不能只用双眼了因为你的双眼肌肉已完全紧绷,但是画任然超出了眼睛的范围,所以你需要使用脖子和头部去看画。继续这么做让画原理你,甚至是朝着你的背部移动。你会观察到你的头和颈部的关节和肌肉都已完全紧绷。你需要转动脊椎和胸椎去看目标。
以下是2种lookat ik的效果对比
0x1 保留动画
为什么用了lookat动画感觉怪怪的?一般我们在LateUpdate中实现IK的计算过程,这会导致Animation的动画被覆盖掉。试想以下一个带有点头动画的Lookat,经过IK算法的调整,动画的rotation被覆盖,讲导致点头动画丢失。
因此在Lookat计算完后,还需要把原先的点头动画给叠加回去。
让我们来看下GDC中DOOM的动图,怪物带有很夸张的腰部转动动作,如果腰部被IK控制而不把原先的动画叠加回去,怪物将不会弯腰:
下面的动图是根据GDC的方案的复刻,动画循环按照 无ik的原版动画->不保留动作的IK->保留动作的IK循环播放。可以看到,如果不把原先的动画叠加回去,动画的仰头和后仰的旋转动画被覆盖,导致人物动作僵直。
0x2 功能对比
todo
0x3 Unity内置的Animator.SetLookAtPosition注意事项
todo