In this post we’re going to re-create the Third Person’s Template project animations in C++. Before reading on, create a Blueprint a Third Person Template project! Since we’re going to use the assets provided with the specific template you don’t need to include the starter content.
In order to handle the animations of our character we need to create an Animation Blueprint. In our case, this Blueprint is going to be based in a C++ class which provides the basic “structure” for the animation blueprint that we’re going to create. Even though this post intends to show you how to handle animations using C++, you will notice that after we type the logic in our code, we will spend the rest of the time tweaking values in Blueprints. This is because using C++ we will be able to achieve the base functionality quite easy, however we do need to tweak some values inside the blueprint in order to have smooth animation transitions, otherwise our animations will look “raw”!
You could say that this post is divided into three parts:
- Writing the base C++ code
- Wiring everything in the Animation Blueprint which is based on the above class
- Tweaking values in the Animation Blueprint to achieve smooth animation transitions.
So, let’s get started!
Part 1: Creating the logic in C++ class
When your template is loaded, create a new c++ class which inherits the AnimInstance class (I named my class MyAnimInstance – we will need that name later!), like the following screenshot:
When the process of adding the class is finished, inside the header file of your class, type in the following properties and function:
/*True means that we're currently in air - or falling*/
/*Holds the current speed of our character*/
/*Updates the above properties*/
UFUNCTION(BlueprintCallable, Category = "UpdateAnimationProperties")
When you’re done with that, switch to your source file and add the following implementation of the UpdateAnimationProperties:
//Get the pawn which is affected by our anim instance
APawn* Pawn = TryGetPawnOwner();
//Update our falling property
bIsFalling = Pawn->GetMovementComponent()->IsFalling();
//Update our movement speed
MovementSpeed = Pawn->GetVelocity().Size();
That’s it… That’s all the code required for this tutorial. Everything else is handled inside the Animation Blueprint! Compile your code and switch to your editor.
Part 2: Creating the Animation Blueprint
Somewhere inside your content browser, right click and create an Animation Blueprint:
When you choose the above option, a menu will pop up. You need to select the parent class and the target skeleton for your Animation Blueprint. In the parent class option make sure to enter the C++ class we created above. Remember that I named my class MyAnimInstace so your select your equivalent option. For the target skeleton, select the skeleton of the Third Person Template Project.
Name your animation blueprint anything you want (I named it Cpp_AnimBP – we will need that later!).
When you create your Blueprint, open it up and inside it’s Event Graph add a call to the Update Animation Properties function we created above, like the following screenshot:
- Switch to your Anim Graph
- Create a new State Machine
- Wire it with the final animation pose (like the following screenshot suggests)
Compile your Blueprint and jump inside your state machine! Since we’re recreating the Third Person’s Tempate project animation, our state machine will contain the same logic. So, create the following states (they are identical to the default AnimBP which comes with the template):
Now that we’re done with that, we need to provide the logic for the transitions.
This is the transition rule from the Idle/Run to JumpStart state:
This is the transition rule from the JumpStart to JumpLoop state:
I copied the value 0.1 from the default blueprint logic. In a real scenario, you may want to expose that from C++ and tinker with its value, depending on your animations!
This is the transition rule from JumpLoop to JumpEnd state:
And the last transition rule from JumpEnd to Idle/Run state is the following one:
Again, I copied the 0.1 value from the default animation BP. You may need to tinker with that in a real world scenario.
Now that we have all the transition rules, we need to enter the corresponding animation in each state.
Inside the Idle/Run state we’ll use a blendspace and provide the MovementSpeed property from our C++ file (the blendspace I used comes in with the Third Person Template Project):
Inside the JumpStart start just play the Jump_Start animation sequence like the following screenshot suggests (Make sure to uncheck the Loop animation Pin in the settings panel):
Inside the JumpLoop state just play the Jump_Loop animation sequence:
Inside the JumpEnd state play the Jump_End animation sequence:
Save and compile your Animation Blueprint.
Go to your Character’s Blueprint and in the Animation category in the Anim Blueprint Generated Class select the Animation Blueprint we created above like the following screenshot suggests:
Save and compile your Character’s Blueprint. When you press the play button and play around a bit you will notice that the correct animations play, however their transition are a bit “clumsy”. This is where the 3rd Part of this post comes into play!
Part 3: Achieving Smooth Animation Transitions
In order to achieve smooth Animation Transitions, we will tweak a bit the values for each transition.
- Select the Transition Rule from Idle/Run to JumpStart and copy the values from the screenshot below:
- Select the Transition Rule from JumpStart to JumpLoop and copy the values from the screenshot below:
- Select the Transition Rule from JumpLoop to JumpEnd and copy the values from the screenshot below:
- Select the Transition Rule from JumpEnd to Idle/Run and copy the values from the screenshot below:
Save and compile your Blueprint. Now you’re animations are identical to the 3rd Person Templates and you know how to handle animations using C++!
PS: In case you want to handle animation montages using C++, inside the AnimInstance C++ class you have the ability to call functions like Montage_Play / Montage_IsPlaying / Montage_Stop and provide a UAnimMontage* parameter.