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"
With both our Left and right controller we need to create a "Select" node. In "Option 0" connect the "Left Controller" and in "Option 1" connect the "Right Controller". For the "Index" we need to switch this to Bool which we connect our "Left/RightHand" Bool Variable which we created earlier too.
Now from our "Select", we can get our "Hand Mesh", and from the Hand Mesh we can "Get Anim Instance" Now we can "Cast to RightHandAnimBP" where we can start setting our hand animations to use.
From our "Cast To RightHand_AnimBP" execute pin we need to add a "branch" node and use our "Set Animation" Bool to the condition
From Our "Cast To RightHand_AnimBP" drag of the blue pin "As Right Hand Anim BP" and get "Set Animation". Do this Twice.
Connect one "Set Animation" to the "True" output and the second to the "False" output.
You will need to make sure the "Set Animation" Bool coming from the "False" execute is set to true and the "Set Animation" from the "True" pin is set to false.
The next step is to Set our "Grip State" to do this we need to drag off the blue pin from our "Cast to RightHand_AnimBP" in my case I'm going to drag off the reroute I've created. After dragging of were going to "Set Grip State". We need to do this twice. for our "True" and "False" channel.
After adding the "Set Grip State" Twice your graph should look something like this.
The last thing we need to do in our "Actor Component" is set our "Grip State" from our "True" Channel to use our "HandAnimationToUse" Variable we created earlier. Make sure the "Grip State from the "False" channel is set to "Open"
Our completed "Actor Component" should now look like this.
We can now close our "AC_SetHandAnimation" window and head back over to our "BP_PickupCube"
Now we're back in our BP_PickupCube we can add our "AC_SetHandAnimation" Component that we just created. To do this got to "Add Component" in the top left and search for "AC_SetHandAnimation"
With our "AC_SetHandAnimation" component added to the blueprint, we can drag a reference to it into the event graph. From here we're going to drag off the blue pin and search "Call Function" to easily find our custom event named "Set Hand Animation"
Do this twice because were going to need one for when we pick up our actor and we will need another for when we release it. You will need to connect them up similar to the image below.
Now with both events connected we need to add or "AnimationToUse" Variable to the event attached to our "Event Pick Up", the top one.
With the "AnimationToUse" attached we can now connect the "AttachedTo" from our "EventPickup" to our "Get Hand" inputs. We also need to make sure the "Set Hand Animation" node connected to our "Event Pickup" has "Set Animation" Bool set to "True".
And the "Set Hand Animation" node connected to our "Event Drop" has the "Hand Pose" set to "Can Grab"
Before we can test it we need to go into our viewport and set one of our "BP_PickupCube" to use our new rock animation.
By default, all our cubes will default to the "open" animation used in our "State Machine". To do this select a cube and in the details tab, you will now have a section called "Default" This is where we can select our animation to use. So far we only have two animations. In our "State Machine", Open and Rock.
We will cover how to add new animations in the next Blog Post.
Now we have our cube set to use the rock animation we can jump into our headset and try it out.
Ass you can see it allows each hand to use different animations based on what there holding.
And that's how you can create & Implement custom hand animations for VR inside UE4.
Project files are available for download for those who are subscribed to my Patreon.
If you enjoyed this or found it useful please consider Subscribing to my Youtube channel where I post regular VR Tutorials for Unreal Engine 4 and more.
or if you're looking for somewhere to hand out or need help with something VR, Game dev or 3D related maybe consider joining our discord community.
Until next time, stay safe and I'll see you then.