Manchmal reicht die in Unity integrierte IK nicht aus. Ich werde Ihnen zeigen, wie Sie Ihr eigenes IK-Skript für Unity erstellen. Sie können diese IK auf jeden Gelenkkörper anwenden - Finger, Hände oder Füße. Das IK, das ich überprüfen werde, wird derzeit von Unity, Unreal, Panda und mehreren anderen Spiel-Engines verwendet. Es heißt FABRIK.
FABRIK ist eine iterative Methode. Eine iterative Methode ist eine Methode, die die Lösung nicht sofort erhält. Eine iterative Methode kommt der richtigen Lösung mit mehr Iterationen der Methode immer näher - mit anderen Worten, Iterationen einer Schleife.
Jedes IK-Problem hat einen bestimmten Gelenkkörper (eine Reihe verbundener Gliedmaßen mit Längen und Winkeln). Der Endeffektor (die Position des Endpunkts des letzten Gliedes) hat eine Startposition mit einer Zielposition. Es könnte andere Ziele haben, wie z. B. Winkel.
Jede FABRIK-Iteration besteht aus zwei Hauptteilen.
void FABRIK() {
while( abs(endEffectorPosition — goalPosition) > EPS ) {
FinalToRoot(); // PartOne
RootToFinal(); // PartTwo
}
}
Der erste Teil iteriert vom letzten Glied zum Wurzelglied. Für das letzte Glied müssen Sie den Winkel / die Drehung des Glieds ändern, um auf die Zielposition zu zeigen (die Innenbordposition verankert halten und die Außenbordposition durch die Winkeländerung verschieben lassen). Als nächstes verschieben Sie das letzte Glied entlang des aktualisierten Winkels in Richtung der Zielposition, bis die Außenborderposition des Glieds der Zielposition entspricht (wobei der Winkel beibehalten wird, die Innenbordposition des Glieds jedoch geändert wird). Das ist so ziemlich alles für das letzte Glied, außer dass Sie jetzt die aktuelle Zielposition aktualisieren müssen. Die aktuelle Zielposition wird jetzt auf die aktualisierte Innenbordposition des letzten Gliedes gesetzt.
Für jedes aufeinanderfolgende Innenborder-Glied tun Sie dasselbe. Um klar zu sein, werde ich es skizzieren. Für das aktuelle Glied müssen Sie den Winkel / die Drehung des Glieds ändern, um auf die aktuelle Zielposition zu zeigen. Als Nächstes verschieben Sie das aktuelle Glied entlang des aktualisierten Winkels in Richtung der aktuellen Zielposition, bis die Außenborderposition des Glieds der aktuellen Zielposition entspricht. Schließlich aktualisieren Sie die aktuelle Zielposition so, dass sie der aktualisierten Innenbordposition des aktuellen Glieds entspricht.
Wiederholen Sie diese Vorgänge, bis Sie diese Vorgänge am Wurzelglied abgeschlossen haben. Danach ist der erste Teil abgeschlossen.
/* Part One */
void FinalToRoot() {
currentGoal = goalPosition;
currentLimb = finalLimb;
while (currentLimb != NULL) {
currentLimb.rotation = RotFromTo(Vector.UP,
currentGoal — currentLimb.inboardPosition);
currentGoal = currentLimb.inboardPosition;
currentLimb = currentLimb->inboardLimb;
}
}
Der zweite Teil iteriert in umgekehrter Richtung: vom Wurzelglied zum letzten Glied. Für das Wurzelglied müssen Sie seine Innenposition auf die Wurzelposition aktualisieren. Dies sollte das gesamte Glied übersetzen (ohne sich zu dehnen). Das ist so ziemlich alles für das Wurzelglied, außer dass Sie jetzt die aktuelle Innenbordposition aktualisieren müssen. Die aktuelle Innenborderposition wird jetzt auf die aktualisierte Außenborderposition des Wurzelglieds gesetzt. Für jedes aufeinanderfolgende Außenborder-Glied tun Sie dasselbe. Um klar zu sein, werde ich es skizzieren. Für das aktuelle Glied müssen Sie seine Innenbordposition auf die aktuelle Innenbordposition aktualisieren. Dies sollte das ganze Glied übersetzen. Das ist so ziemlich alles für das aktuelle Glied, außer dass Sie jetzt die aktuelle Innenbordposition aktualisieren müssen. Die aktuelle Innenborderposition wird jetzt auf die aktualisierte Außenborderposition des aktuellen Glieds gesetzt.
Wiederholen Sie diese Vorgänge, bis Sie diese Vorgänge am letzten Glied abgeschlossen haben. Danach ist der zweite Teil abgeschlossen.
/* Part Two */
void RootToFinal() {
currentInboardPosition = rootLimb.inboardPosition;
currentLimb = rootLimb;
while (currentLimb != NULL) {
currentLimb.inboardPosition = currentInboardPosition;
currentInboardPosition = currentLimb.outboardPosition;
currentLimb = currentLimb->inboardLimb;
}
}
Nachdem der erste Teil und der zweite Teil abgeschlossen wurden, haben Sie die erste Iteration der FABRIK-Methode abgeschlossen. Fahren Sie mit Teil 1 und 2 fort, bis der Endeffektor so nah wie nötig an der Zielposition ist, die durch ein EPS (Epsilon-Wert) definiert ist.
Das ist es! Das ist die FABRIK-Methode. Teil Eins iteriert vom letzten Glied rückwärts. Teil zwei iteriert vom Wurzelglied vorwärts. Die FABRIK-Methode wiederholt Teil 1 und Teil 2, bis der Endeffektor nahe genug an der Zielposition ist.