Is it worth implementing a custom inverse kinematic system?
Table of contents
- What is inverse kinematics
- Locomotion system
- Test comparison
- For the future
Animating by hand can take a painstakingly lot of time in which other systems must be added to create further realistic interaction with enviroment, like proper foot rotation in relation with the ground and it would be a solution to create custom animation for every interaction in the game and blend them. To solve this problem we could use different algorithims in code to replicate such movements (Johansen, 2021). But is it worth making your own implementation or is it better to use the available packages in Unity?
My inspiration is from a select few games which use a physical body which could interact with the world, but i dont like animating so i searched for a solution where code could solve this problem. I came across a video about character locomotion in Half-Life: Alyx. In the example there is talk about how valve made an AI capable of choosing the right animations and footpositions based on the enviroment and path. I played the game myself and i find the presence of AI super immersive which in turn inspired me to make my own locomotion/kinematic controller.
3. What is inverse kinematics?
What is inverse kinematics and how can we use it to generate procedural generation? Well, kinematics is the study of movement in science. Inverse kinematics is actually originally from the TI-Sector in which the methods was developed for use in the movement of robotic parts (arms). It was developed because there was a problem in moving the arms into position where it could be most useful for picking up objects and work inside the constraints of a real world enviroment. But because we work in a virtual enviroment we can get away with alot of visual tricks that could improve perfomance and or implementation time (Karim et al., 2012 ). So with that out the way how does inverse kinematics actually work? Well this gif is a simple visual that shows the math behind inverse kinematics.
So if you could not get it from the gif, its mostly divided in 2 algorithms, Forward reaching kinematics, and backwards reaching kinematic. Which is shortened and combined to create FABRIK algorithm, Which are called in the main function.
The code below handles the positions, starting from the root to the tips. but places the last joint effector on the goal position, and the solves the rest of the bones and then puts the root back in to place. And to correct bending towards the most preferred direction i used a hint direction on every effector.
It follows the target, but completely ignores the bone lengths and just stretches them until it reaches the target position. And the hint and target put the almost the same amount of influence on the algorithm.
This piece of code just handles the positions of the different joints. It calculates the position of every joints from the root to the tip bone. Thats why its called forward kinematic which is the easy part. And also keeps the backward algorithm in check.
The bones positions are correctly being updated, only the rotations dont match up.
But after the handling all the positions there is a need to correctly rotate the different joint towards the right direction, this part still needs some tweaking.
The bones and skinned mesh now rotate with the positions towards the right direction.
4. Locomotion system
If you would be working on AI movement in games its would be more important to make it look good, the player will notice very quickly if there is something wrong with AI locomotion which would break immersion. If you would be implementing a locomotion system for it would most likely be done like the image on the right. Half-Life: Alyx has a perfect example for this. Because you know where the AI is going to move using pathfinding so it would be a lot easier to implement such a system. But unfortunatly i want to have a playercontroller with reactive legs which is a different situation to be handeling and has completely different criteria. So we have to make sure it can immediately react on direction changes which sound easy but is hard in practice. To use inverse kinematics to make beliveable animation we need to first figure out how to move the points.
To actually move the points i use a Rigidbody velocity to calculate the foot positions. I just created the farthestpoint thats inside the chosen distance, and then place a point where the target can Slerp to. And if the point get out of a range then place the position back towards the velocity inside the max distance of the circle.
After applying the code the legs move in a pattern which could be better controlled after more iterations.
Using the resetwalk function i can change the resting position and the max distance the feet could go. I use slerp to move from points with a easing effect.
The result is that when the Rigidbody stops moving the foot to resting position.
I also applied foot kinematic using a raycast downwards towards enviroment objects, where i then use the raycast normal to rotate the foot to a believeable angle, this also incorporate jumping.
When using footIK the result looks more believeable, the foot aligns with the floor.
Then i call the functions from before in the FixedUpdate() to change offset to change walking style based on the direction of the movement.
Here you can see the different offsets and combined algorithms in action. The end result looks okay, it could be much better with more iterative work and seems really promising for a short experimentation round.
5. Test comparison
To check if i had reached my goal, i made them use the same script with a couple alteration to make it be able to use TwoBoneIKConstraint from the Unity Animation Rigging package.
I built a inverse kinematic solver from scratch which you could see in action. As you can see there is still alot to improve such as more advanced rotation handling such as rotation constraints. But because you have full control over the code it can made to fit more use-cases than the animation rigging package.
Then i created in (one day) the same kinematic solver but using the Animation Rigging Package, TwoBoneIKConstraint. It looks a little better and also handles rotation constraints and positions by default. But the biggest difference is the implementation time. If you were going for that then this is the right solution.
When showing the difference of chosen solutions to (currently) 4 game-developers, they could not see a difference at first glance. Or at least they cant quite put a finger on what is off about the movement. So that conclude that its a better option to stick with the animation rigging package to save a lot of time on implementation of IK and shift the focus more on what makes locomotion look good and what improvements could be made.
Using a Inverse kinematic library or using the built in IK-system in Unity saves a lot of time and headache. I had to learn a lot about rotations which if you didnt know are pretty hard to get right. So instead i recommend using a library or a solver to solve it for you because what matters more is implementing a realistic looking locomotion system. If you have knowledge about physics and or rotations in general, or have a special use-case you might be able to innovate by creating your own custom implementation.
7. For the future
For the future i want to use the fabrik algorithm to also move arm positions and also make it foolproof, this means that the technique could be useable in every part of the movement. For example we can use the technique to move arms to doorknobs to physically pull or push the objects. Also this only works on bipedal humanoids in which it could be extended to cover more use-cases. Also what could be improved upon is implementation of rotation constraints which could make it more easy to implement and also makes it alot more believeable. Also wat could be implemented is heel/toe offset technique like the example of Half-Life:Alyx, and also add an arc in movement in which it could look like the character is actually lifting their legs and would increase the believeability of the end result.
1. Character Locomotion in Half-Life: Alyx – SIGGRAPH 2021. (2021, 8 oktober). [Video]. YouTube. https://www.youtube.com/watch?v=RCu-NzH4zrs
2. C# Inverse Kinematics in Unity. (2019, May 11). YouTube. https://www.youtube.com/watch?v=qqOAzn05fvk&t=428s
3. Karim, A. A., Gaudin, T., Meyer, A., Buendia, A., & Bouakaz, S. (2012). Procedural locomotion of multilegged characters in dynamic environments. Computer Animation and Virtual Worlds, 24(1), 3–15. https://doi.org/10.1002/cav.1467
4. Inverse Kinematics for Procedural Animation – HVA GPE Game Lab – Fall 2021. (2021, 25 oktober). Game-Lab. Geraadpleegd op 11 april 2022, van https://summit2021b.game-lab.nl/2021/10/25/inverse-kinematics-for-procedural-animation/
5. iRadEntertainment. (2021, 15 juni). My tests with Inverse Kinematic using FABRIK for future procedural animation [Reactie bij het artikel “Godot-FABRIK-2D”]. Reddit. https://www.reddit.com/r/godot/comments/o0jkpe/my_tests_with_inverse_kinematic_using_fabrik_for/
6. Johansen, S. (2009, 25 mei). Locomotion System – runevision. https://runevision.com/. Geraadpleegd op 11 april 2022, van https://runevision.com/tech/locomotion/
7. Test results