[UE4藍圖]虛幻4中完整實現腳部IK(一)
先上
演示圖
上下坡都有效,不受膠囊體碰撞的影響
腳部完全貼合地面
何為IK?
IK(Inverse Kinematics),
反向運動學
,是指在一個相互連結的動力鏈中,移動某一個節點時(特別是當最末節點移動時),其他節點的引數會自動計算以達到期望的位置。
簡而言之,
IK 是給某個骨骼直接設定一個目標位置,讓系統計算其它骨骼的旋轉和位置
。比如抬腿時,可以將腳的位置向上偏移,然後控制好膝蓋彎曲的方向(向內側或者外側),系統則會計算出膝蓋應該處在什麼位置。
(FK(Forward Kinematics),
正向運動學
,則是按順序設定每個骨骼的位置與旋轉)
主要原理:
先看這張圖
圖中
虛線
是人物左腿本來的位置,
實線
是實現IK後左腿應該所處的位置,
綠色圓圈
是膝蓋位置,
紅色線段
是腳抬高的距離。
也就是說,我們只要讓左腳移動紅色線段的位移,就可以實現IK了。那麼我們需要用到
射線檢測
來計算出這段位移。
看一下射線檢測圖
圖中
藍色
即為我們檢測用的射線,從
人物半高
位置豎直打向左腳。
紅色部分
則為射線的擊中點,
綠色圓圈的高度
是地面的高度,也就是人物Mesh元件的高度(Mesh的座標點在腳下)。紅黑長度可以由射線檢測得到,綠黑長度即為
人物半高
(你也可以設定為其他定值)。
那麼腳的偏移量
紅綠長度=綠黑-紅黑
便可以求得了,膝蓋的位置就交給IK系統處理了。
(
關於人物膠囊體碰撞框導致腳部接觸不到地面的問題,下一篇會講
)
完整實現:
1。照例新建一個ThirdPersonCharacter模板工程,找到Player的AnimBP並開啟。
2。在AnimBP中的AnimGraph裡新增兩個TwoBoneIK節點
TwoBoneIK節點
:雖然叫TwoBoneIK,但其實需要有三個相連的骨骼才可生效。
那麼在我們這裡顯然是
foot(腳部)-calf(小腿)-thigh(大腿)
。
一個
End bone
(即設定的IK bone,foot),一個
Joint bone
(End bone的父骨骼,calf),一個
Root bone
(Joint bone的父骨骼, thigh)。
這裡先提一句,
foot的骨骼即為膝蓋連線到腳踝的這一根骨頭,因為控制的是foot所以命名為foot
,同理calf是大腿根連線到膝蓋的骨頭,thigh是胯部連線到大腿根部的骨頭。
簡單的說,
我們控制的只有EndBone。
透過End bone的位置,Root bone的位置以及我們等會設定的Joint Target location(
注意這是TargetLocation,並不是指Joint Bone的location
)
三點可以確定一個平面
,而大腿小腿的長度是固定的,那麼calf也就是膝蓋的位置就確定了。(ue4提供了骨骼拉伸的功能只需勾選Allow Stretching,有興趣可以嘗試)
3。以左腳為例,我們設定第一個TwoBoneIK的細節,從上到下依次解釋。
IK
:前面說過,IK Bone就是End Bone,我們要控制的骨骼,自然選擇foot_l,其他不用更改。
Effector(執行器)
:用來控制要怎麼移動IK Bone。
Effector Location Space(執行器位置座標系)
:選定移動IK Bone時的座標系。
有四種,
WorldSpace(世界座標系)
,
ComponentSpace(元件座標系)
,不用多說。
BoneSpace(骨骼座標系)
,以你選定的骨骼為原點的座標系。
ParentBoneSpace(父骨骼座標系)
,以你選定骨骼的父骨骼為原點的座標系。
這兩個其實也是差不多的,假如選擇ParentBoneSpace然後EffectorTarget選擇了腳趾,跟BoneSpace選擇腳部是一個效果,因為腳部是腳趾的父骨骼。
(我確實沒有理解這兩個座標系在哪些情況下使用會有明顯差異,如果有大佬知道,希望能評論告訴我一下,十分感謝。)
那麼我們透過
射線檢測算出的距離等於是基於左腳座標系的偏移量(且只有豎直方向上)
,所以選擇BoneSpace和foot_l。
Jonit Target(關節目標)
:這個座標系選取也是BoneSpace比較好,但骨骼其實選擇大腿或者大腿的父骨骼或者其他骨骼其實都可以用,我們這裡直接選擇thigh_l(左大腿)。
4。我們選中TwoIK節點後,可以在左側視窗直接調整EffectorLocation和JointTargetLocation的值。看了這個圖,應該能理解到EffectorLocation和JointTargetLocation了。(
EffectorLocation是遊戲執行時實時計算的,只有JointTargetLocation的值是需要固定的
)
如果你將這兩個值提升為變量了,就拖不動了,只能透過修改變數值來更改
最需要注意的是,更改EffectorLocation時,可以發現腳部豎直向上位移的時候,變化的是X軸,這是因為根據的座標系是基於左右腳的,並且左右腳還是相反的。
左腳向上位移時X值增加,右腳向上位移時X值減少。
JointTargetLocation其實有點難調,實在懶得調可以參考一下我的值(前提你的TwoboneIK設定必須跟我一樣),然後
將左右腳的EffectorLocation的X值都提升為變數
,預設值0。(因為我們只需要腳在豎直方向位移)
5。開啟人物藍圖,在BeginPlay事件中獲取到
動畫藍圖
並提升為變數,將
膠囊體的半高
也提升為變數存起來,方便後面使用。
6。新增一個射線檢測函式IK_LineTrace,先看下射線路徑圖再寫藍圖
透過腳部的XY軸值和Mesh的Z軸值獲得了
藍點
,
藍點加上半高就得到射線的起點
,
藍點減去TraceDistance就得到射線的終點。
(
為什麼不用腳部的Z軸值
?因為我們修改的EffectionLocation是給腳部的偏移量,而初始位置都是在地面的高度也就是Mesh的Z軸值。當腳已經實現IK抬起時,腳部的Z軸值就已經不是在地面位置了,就會出現計算出的位移量錯誤。)
藍圖實現
藍圖跟上面路徑圖保持完全一致,函式需要兩個輸入,
BoneName(骨骼名)和TraceDistance(射線在地面下方的長度)
現在處理射線檢測的結果
用半高(上圖中紅色)- HitDistance(射線起點到擊中位置的距離,上圖中紫色)= 腳部所需位移距離(也就是腳踩的箱子高度)
(
SelectFloat節點
:如果輸入的Bool型別為True,則輸出A,反之輸出B。這裡射線沒檢測到物體時,自然返回0)
7。在Tick事件中呼叫IK_LineTrace函式
先檢測左腳(注意BoneName一定不要填錯),然後返回值賦給AnimBP的Effector LocationXLeft,右腳同理,只不過需要
求相反數
,因為之前提到過,兩隻腳的X軸方向是相反的。
為了先去掉膠囊體碰撞的干擾,我們先把膠囊體的CapsuleRadius(半徑)調小調到10
現在進入遊戲,當人物站在樓梯上不動時,已經實現了IK了(建議先用一個寬一點的臺階易於觀察,跑起來腿部不自然和抖動以及其他的問題後面都會解決)
在遊戲中按下~鍵開啟控制檯,輸入show collision可以將碰撞框顯示出來
一直在說膠囊體的問題,下面這張圖就可以清晰的展示了
可以看到,膠囊體把人擋在了上一級臺階,所以左腳拉不下去了,下一篇我們會來解決這個問題。
下一篇
感謝關注評論點贊收藏!有問題請評論或私信。