本文集合了我在實作 Foot IK 時所看過的參考資料。由於網路上需多不同的資源都只提到其中某一種特定的實作方法,每一種方法又有不同的限制與需要注意的細節,資訊十分分散。所以寫了這一篇文章,希望能總結出它們的共通點與差異,藉此掌握其中的精髓。


資源


介紹

在遊戲開發中,角色的動作往往是根據 animation clip 中的關鍵幀呈現出來的,不做任何調整的結果就是缺乏通用性。通用的動畫通常只適用於角色位於平面的情形,當角色處於起伏不定的坡面、階梯時,還保持站在平面的懸空狀態就會很不自然。

左側模型無設置足部 IK 所以一腳陷入地面一腳懸空,右側模型是 IK 正在運作的表現。

左側模型無設置足部 IK 所以一腳陷入地面一腳懸空,右側模型是 IK 正在運作的表現。

使足部貼合地面的演算法大致包含兩大階段,首先是尋找著地點的位置 (position)法向量 (normal),這個步驟在我看過的 implementations 中沒有太大地差異,普遍使用 Raycast 朝地面打一道射線尋找 collider,但是其中潛藏著實作時可能會遇到的一些錯誤,需要進一步修正。接下來就是要根據找到的目標調整骨架位置,從目標位置回推姿勢就是所謂的反向運動學 (Inverse Kinematics),在Unity中想要運用 IK 有許多方法與套件,這篇文章中將會介紹到三種方法:

  1. Unity 的 Animator 中內建的 IK (Inverse Kinematics) 系統,有包裝好的 API 供開發者輕鬆使用,不用考慮背後具體的實現流程,但只適用於 Humanoid 骨架。
  2. Unity 官方的 Animation Rigging 套件,提供更多元的功能,可附加在所有種類的骨架,但靈活性的需要
  3. 手刻 IK,只需要一…點點中學程度的三角函數與 Vector3, Quaternion 的操作。

📥 地面探測

這裡唯一會用到的函式是 Physics.Raycast,它的作用是沿著一條直線探測途中撞到的 collider,有多個 overload,這裡舉一個典型的例子。

bool Physics.Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance, int layerMask)