Previously we learned how we could create our own Avatar on the Ready Player Me website, import it into Unity and animate the upper body with the help of inverse kinematics. If you haven’t checked out the first part of this series, we highly recommend checking it out, since the skills and knowledge from it are required here as well.
In this blog post, we’ll learn how the lower body can be animated. The VR hands are tracked using the two controllers, to animate the legs using real-time tracking, you would need additional trackers. But, since most people (like me) don’t have them we would like to propose a different solution: Downloading or creating animation for the lower body and playing them whenever the user moves. 💃🕺
Generally, to animate the legs we need to download the animation separately and add it to the avatar. But, the Ready Player Me avatar comes along with walking animation.
Now if you hit Play and observe what happens, you will notice that:
So, we need to correct two defects here. One is to stop the walking animation from affecting the upper body and the other is to stop the leg from passing through, which we will address in the next section.
Now, to stop the animation from affecting the upper body:
Now when you click Play▶ you will notice that the animation looks a lot better.
To solve the second issue which is the leg passing through the floor, we need to animate the legs procedurally to make sure the legs bend when the upper body is crouching and pass through the floor. For that, we’ll write some code that makes use of the API methods of the Animator component like GetIKPosition, SetIKPosition, SetIKRotation, etc to procedurally animate the legs.
In the Project window, create a new C# script, name it as AvatarFootController and copy the following script. In the next section we have the breakdown of the code as well, so don't worry if you are not able to understand the math behind the code immediately.
This section will help you understand the code, feel free to skip to the next section if you understood the code already.
VariableNameTypeUseanimatorAnimator To assign the Animator component and use its properties
.leftFootPosWeightfloat To store the value between 0 and 1.
The value will determine the influence the left foot IK position will have on the animation
.rightFootPosWeightfloat To store the value between 0 and 1.
The value will determine the influence animation will have on the right foot IK position
.leftFootRotWeightfloat To store the value between 0 and 1.
The value will determine the influence animation will have on the left foot IK rotation
.rightFootRotWeightfloat To store the value between 0 and 1.
The value will determine the influence animation will have on the right foot IK rotation
.footOffsetVector3 To store the offset value between the ground surface and the avatar’s feet
.raycastOffsetLeftVector3 To store the offset value for the point of origin of raycast from the left foot
.raycastOffsRightVector3To store the offset value for the point of origin of raycast from the right foot.
The method OnAnimatorIK() is called by the Animator Component immediately before it updates its internal IK system. This callback can be used to set the positions of the IK goals and their respective weights.
💡 An IK goal is a target position and rotation for a specific body part. Unity can calculate how to move the part toward the target from the starting point (ie, the current position and rotation obtained from the animation).
First, we’ll understand the code for the left leg and the same can be applied for the right leg but with different variable names.
The following GIF is for a better understanding of how the weights affect the IK animation. In the coming section, you will see how to implement the same.
We want to play the walking animation when the joystick/trackpad is used to move forward or backwards right? For that, we’ll write another script that will take the Input Reference as a parameter and play the animation when the movement input action is triggered.
💡 You can even play the animation by tracking the head movement. This will be useful when the user walks in room space.
Before we are writing the script we will have to set up the Animator by creating two parameters that can be accessed via script and also add a new state to transition from Walking to Idle state.
In the Project window, create a new C# script, name it as AvatarAnimationController and copy the following script. In the next section we have the breakdown of the code as well, so don't worry if you are not able to understand the math behind the code immediately.
This section will help you understand the code, feel free to skip to the next section if you understood the program.
Variable NameTypeUsemoveInputActionReferenceTo store the reference to the input actions. In our case, we will store the continuous move input action.animatorAnimatorTo assign the Animator component and use its properties.
To store the reference to the input actions. In our case, we will store the continuous move input action.animatorAnimatorTo assign the Animator component and use its properties.
The function AnimateLegs get called when there is a callback from the event of input reference. So, when the function gets called,
The function StopAnimation also get called when there is a callback from the event of input reference. When this function gets called we will set the Bool parameter isMoving to false so that the animation will transition from Walking to Idle. Also, we will set the speed to 0.
Now let's add the components that we created and set it up to make the lower body animation work.
With that, we have finished animating the lower body. Now you can test the scene in VR and experience it.
There are many more improvements that can be done. The AvatarFootController values can be further tweaked to get a better experience.
You can also make use of a blend tree to have different animations for different types of movements. Also, you can upload this avatar to Mixamo, download other walking animation and add it to your Avatar as well.
If you've enjoyed the insights shared here, why not spread the word? Share the post with your friends and colleagues who might also find it valuable.
Your support means the world to us and helps us create more content you'll love.