Creating & Implementing custom hand animations for VR in ue4. (Part 1)
Updated: Dec 3, 2020
(Part 1) Setting Up Custom hand animations in VR can be crucial in creating a fun and unique user experience for those playing your games. In this blog post, we're going to go through step by step and look at how you can create your own custom posses which fit your project. And the best part, We can do this without any other software. Let's get started.
For this tutorial, I'll be using the default VR template available within UE4 (I'm using 4.25.2) but this will work with any version. I start by setting the Map to "Motion Controller Map" and make sure its set to load in the project settings. If your not sure how to do this go to Project Settings, Maps and Modes and then set "Editor Startup Map" and "Game Default Map" to use the "Motion Controller Map". Now your good to go.
1. Creating a new hand animation for us to use within UE4.
Before we can start creating our code we need to begin by creating a new animation for us to use. This is really simple to do within UE4. The first thing we need to do is navigate to our hand animations folder inside our Content Browser. In the default template, this is located in the Virtual Reality folder, Mannequin, Animations.
Here we can use one of the provided examples as a base for our animation, In this example, I'm going to create a rock pose. Where our Middle and Ring finger are tucked into our palm. And for this, I'm going to use the "Mannequin_Hand_Right_Open" animation which is provided. Double click the animation to open it up. It should look something like this.
To Pose the hand to our new animation we need to see our bones you do this by going to the "Character" drop-down in the top left of our Viewport, "Bones" and enable "All hierarchy"
This lets us see our bones and gives us the ability to pose them how we wish. We can do this by selecting the bone attached to the finger we want to move and use the transform tool to rotate it to the location we want it to be at.
If you're having difficulty selecting the bones you want to manipulate you can go to "Character" "Mesh" and Temporarily disable the "Mesh"
It should look something like this (or your custom pose) once you're done.
Hitting save here won't do anything so we now need to export or new hand pose so we can save it. To do this go to "Create Asset" in the top left of our viewport, "Create Animation" and select "Current Pose".
You will now be prompted to select a path to create your new animation. To keep things organised were going to select our "Animations" Folder and set our "Animation Name" I prefer keeping the naming similar to what is already being used. So I'm going to name mine "MannequinHand_Right_Rock"
And that's all it takes to create a custom hand animation within UE4. We can now close the hand pose window as we don't need it anymore and if we check our "Animations" folder we will see our new animation.
2. Add our new animation to our existing "GripEnum"
This is located in our "VirtualRealityBP", "Blueprints" folder. You're going to want to open it up and create a new Enum and name it appropriately. In this case, I'm calling mine "Rock" as that's what I've called my animation.
Now we can close our grip enum and we can start setting up our animation State Machine which is going to let us choose which animation to use.
3. Setting Up our Animation Graph
before we create our "State Machine" we need to set up our "Animation Graph" But first we need open our "RightHand_AnimBP" you can find it in the same place our custom hand animation is located, in the "VirtualReality", "Mannequin", "Animations" Folder.
It should look something like the image above. This is where we are going to create our "State Machine" so we can switch our animation but before doing that we need to create a "Bool Variable" called "Switch Animation" and were going to drag it into our Animation Graph. So it looks like the image below.
The Next thing we need to do is create a "State Machine" which we can do by right-clicking in our viewport and searching "State Machine"
Once you've created it gives it an appropriate name, I called mine "Hand Pose" as that's what it's going to contain. Your "AnimGraph" should look like this now.
The next thing we need to do is create a "Blend" node so we can blend between our animations. We do this the same we created our "State Machine", Right-click and search "Blend" I needed to scroll to the top of the list but we just need the default "Blend" node.
With the "Blend" node selected, navigate to the details panel on the right-hand sides and change the "Alpha Input Type" to "Bool Value" By default, this "Blend" Node will make our animations Snap between each other so we need to change the "Blend Settings".
With the "Blend" node still selected open the "Blend Settings" drop-down and change both "Blend in Time" and "Blend Out Time" to "0.1" if you want your animations to blend slower you can increase this number to something higher but I'd recommend staying bellow "0.5"
I'd also suggest changing the "Blend Option" to Cubic for a smoother transition. If you're not sure which one to use open the drop-down and hold "Ctrl + Alt" to see how the animation curve looks.
So far your "AnimGraph" and "blend" settings should look like this.
The next step is to begin hooking up all our different nodes but before doing that we need to invert our "Switch Animation Bool" using a "NOT Boolean" node. The image below shows how the graph should look once everything is connected and organised. I added some comments to make it easier to understand if we need to return in the future.
Before We update and set up our "State machine" we need to navigate to the "Event Graph" at the top of our viewport and create a branch using our "Switch Animation" Boolean. Our "branch" is going to be located between our "Event Blueprint Update Animation" node and the "Set Grip Float" node. Were then going to use the "Switch Animation Bool" we created to open and close the branch. By default, the "Switch Animation Bool" should be set to False.
You need to set up the "Branch" so the input comes from the "Event Blueprint Update Animation" into the branch and the "True" channel connects to the "Set Grip Float"
Your "Event Graph" Should look like the image below.
If you hit compile you may notice some "Warnings" in the "Compiler Results" tab, Don't worry we're going to fix them now.
Update - Once you get to testing, if the hands don't close to fists when you first put on the headset but change after interacting with and object set the "Switch Animation" Bool to "True" in the "RightHand_AnimBP", Not from the variables tab though. just select the one in the viewport and set its "Default Value" to true.
Now we need to head back to our "AnimGraph" and enter our "Hand Pose State Machine"
you should be greeted by a node named "Entry"
This is where we can start setting up our custom animations. But before we do we need to create a new "State" called "Open" This is going to be our fall back animation which by default is the "MannequinHand_Right_Open" To create the new state simply right-click in the "HandPose" graph and select "Add State" and name it "Open".
Now connect the "Entry" node to it, it should create an arrow pointing from "Entry" to the "Open" state. Like the image below.
Double click the "Open" node so you enter it. In here we need to add our "MannequinHand_Right_Open" animation from the Asset browser list in the bottom right of the window/screen. Drag it in and connect it to the "Output Animation Pose" now if we hit "Compile" our warnings will disappear.
Now we need to go back to our "Hand Pose" graph. Select it from the top of the window, it's easier. Now we need to create a new "State" for our "Rock" pose.
After creating the new "Rock" state you need to connect it to the "Open" state. To do this drag of the ring around either "State". You will need to do this from both of them to create two transition states going back and forth. It should look like this.
The next thing we need to do is enter the transition rule from the Open to Rock, you do this by double-clicking the circle. In here we can specify our rules for switching our animation and to do this we are going to use the "GripState" Variable in our variables tab on the left. Drag it in and select "Get"
You then need to drag of the "Grip State" pin and search "==" here we need the "Equal (Enum) node.
Connect the "== (Enum)" to the "Result" node. Now from the drop-down select the animation your using, in this case, it will be "Rock"
Hitting "Compile" will remove the "Warning" Now we need to go back and set up the next transition state. That will be the Transition going from "Rock" to "Open".
In this "Transition Rule," we need to use the "Grip State" variable and drag of it so we can get the "NotEqual (Enum)" node.
Plug this into the "Result" Node and change the "NotEqual" drop-down to "Rock"
We've now successfully set up both our "Transition States" now we need to tell our "Rock State" which animation to use. Go back to the "Hand Pose" Graph and double click on the "Rock State".
Once you're in the "Rock State" you will need to connect the "MannequinHand_RightRock" Animation to the "Output Animation Pose"
We're now done with our "RightHand_AnimBP" I will revisit this later when I explain how we can quickly add more animations.
So, for now, we can close this window and return to our Viewport. As we need to make a quick change to our "BP_MotionController"
This is found in the same file as our "GripEnum". "VirtualRealityBP", "Blueprints" and we are going to open or "BP_MotionController" Make sure you're in the "Event Graph" as this is where we are going to add our code.
Make your way to the commented sections titled "Update animation of Hand" and "Update the animation state of the hand mesh" this is where we will put our code.
Currently, the hand "RightHand_AnimBP" is firing every tick which will override any animations we add, so we need to stop this from happening. and we can do this by creating a new "Bool Variable" called "OverideAnimation" this needs to be set to "False" by default.
Once you have created the the "OverideAnimation" bool you need to set it just after the sequence node in the "Update animation Hand" section. connect the "Attached Actor, NOT Equal" node to the bool Input. then from the Set node-connect it back to the "OR" node. It should look like the image below.
You then need to create a Branch node between the "Cast to RightHand_AnimBP" and the "Set Grip State" the "Grip State" should be connected to the "False Channel". It should look like the image below.
That's it for modifying the "BP_MotionController" so go ahead and close it as we don't need it anymore.
4. Creating Our Custom Actor Component.
Before creating our custom "Actor Component" we need to add our "GripEnum" Variable to our "BP_PickupCube" so we can choose which animation we want to use for individual objects.
Navigate to the "VirtualRealityBP" folder and then the "Blueprints" Folder. in here open up the "BP_PickupCube" This is going to be the base blueprint we use for any interactable we want to add to our game.
In the "BP_PickupCube" navigate to the Variables tab and create a new variable named "AnimationToUse" you then need to set the Variable Type to "Grip Enum" and make sure the "Default Value" is set to "Grab" this is will be the default animation to use.
You also need to make the "AnimationToUse" Variable "Public" so we can change this in the scene.
I recommend minimising the BP_PickupCube window as we will need it again later on.
We can now begin creating our "Custom Actor Component" which will be in charge of changing our animation.
To do this right-click in your "Blueprints" folder located in your "Content Browser" and Navigate to "Create Blueprint Class"
Select "Blueprint Class" and select "Actor Component"
As Unreal's description explains "An ActorComponent is a reusable component that can be added to any actor." Basically, we can write our code once and reuse it as much as we want in different places or on different objects.
Select "Actor Component" and you'll be asked to name it I use the Prefix "AC_" for Actor Component so I can easily search for it in the future if needed.
I named mine "AC_SetHandAnimation"
Open our newly created "Actor Component". in here we're going to create three variables and a Custom Event which will be controlled by our "BP_PickupCube" once we add it.
The first three Variables we need to add is:
a bool called "Set Animation"
a bool called "Left/Right Hand"
our Grip Enum called "HandAnimationToUse"
Both Bools should be false and our "HandAnimationToUse" should be set to Open.
The Next step is to create a "Custom Event" and name it "Set Hand Animation"
With Our "Custom Event" selected we need to add three inputs.
The First being our "GripEnum" named "Hand Pose"
The Second a "Boolean" named "Set Animation"
The Third an "Object" variable named Get Hand"
Now we can start putting our code together. Were going to start by setting all three of the variables we've created.
With all three variables dragged into the graph connect them as shown below.
We now need to drag off the "Get Hand" pin from our "Set Hand Animation" event and get display name.
From display name were going to get a "Contains" found under the "String" heading.
In Substring type "1" this will get our second controller. We then plug the Return Value into the "Set Left/Right Hand" Bool. It should look like the image bellow.
The next thing we need to do is Cast to our "MotioncControllerPawn" so we can get our hands.
Were then going to use the "Get Player Pawn" node as the cast too's object.
Now we are casting to our "MotionControllerPawn" we need to get both our left and right Controllers, We can do this by dragging of the "As Motion Controller Pawn" pin and searching for the "Left Controller" and then repeating the process for the "Right Controller"