Foot IK in Unity

"Neulich", also zwischen Weihnachten und Neujahr, habe ich mich mit inverse kinematic beschäftigt. Tutorials gibt es da insbesondere für Unity so einige, aber ich muss sagen, die meisten sind nur aus der Kategorie zusammengetippt und die Erklärung dahinter ist eher rudimentär. Long story short, ich möchte hier das Konzept für foot IK kompakt darstellen und erklären. Ich vermute einfach mal, wer hier liest wird schon wissen, was foot IK denn überhaupt ist, falls nicht nur ganz kurz: mit foot IK kann man die Position von Füßen in einem Spiel dynamisch an die Situation anpassen. Wenn z.B. ein Stein unter einem Fuß ist, soll dieser Fuß natürlich nicht im Stein verschwinden, es sieht viel besser und realistischer aus, wenn der Fuß auf dem Stein steht und im Idealfall noch einen passenden Winkel annimmt.

Grundkonzept von Foot IK, relativ zur Position: in diesem Fall wird ein Fuß etwas nach unten versetzt, das andere Bein muss natürlich angewinkelt werden.

Wie funktioniert Foot IK?

Stichpunktartig so:

  1. Vom Fuß aus bzw. etwas darüber einen Raycast durchführen und damit die Position des Bodens für den Fuß ermitteln
  2. Fuß entsprechend positionieren und auch drehen (in gewissen Limits, optimalerweise) FALLS man mit der Animation nicht festgelegt hat, dass Foot IK für DIESEN Fuß in DIESEM Moment nicht greifen soll oder einfach weniger stark eingesetzt werden soll. Dafür erstellt man Kurven in der Animation, ich habe die "LeftFootIKCurve" und "RightFootIKCurve" genannt. Und weil man in .anim keine Kurven hinzufügen kann, sind die ziemlich ungeeignet für IK. Naja, zumindest geht das nicht ohne Verrenkungen.
  3. Anschließend noch die Höhe der Hüfte anpassen, sonst wirkt das sehr unnatürlich - je nach Situation.

Stolpersteine

In vielen (älteren) Tutorials wurde die Position der Füße für den Raycast in Update() abgefragt (Beispiel, trotzdem sehr gutes Tutorial: https://www.youtube.com/watch?v=EggUxC5_lGE). Das ging bei mir so nicht, weil der Animator dann die Position der Füße noch nicht aktualisiert hat.

Mögliche Optimierungen

Ich hatte die Idee - aber noch nicht ausprobiert - man könnte durchaus wenn ein Fuß angehoben wird komplett auf den Raycast verzichten, denn wenn sich der Wert der Left-/RightFootIKCurve Null annähert, ist die Umpositionierung ja eh nicht mehr gegeben. Aus dem Bauch heraus vermute ich mal, unter 0.15 kann auf den ganzen Käse verzichtet werden, wenn es auf Performance ankommt.

Alternativ könnte man den Wert nutzen, um die grenzwertigen Fälle noch ein bisschen zu verbessern. Der Logik nach funktioniert dieser Algorithmus tendenziell schlecht bis sehr schlecht, wenn es darum geht z. B. Treppen zu laufen, weil die Stufen ja ignoriert werden, solange ein Fuß in der Luft und die IKCurve nahezu Null ist. Ein schlüsselfertiges Konzept hab ich noch nicht, aber man müsste wohl prüfen, wie weit der hit des Raycasts vom Fuß entfernt ist und danach entscheiden, ob man den niedrigen Wert aus der IKCurve ignoriert und stattdessen einen höheren Wert nahe 1 verwendet, um einen angehobenen Fuß trotzdem per IK zu positionieren.

Beispiel auf Github

Meinen Code findet ihr hier: https://gist.github.com/JoernSchoenyan/06d2a371bdc81161a88b0bb71a29355b