While our game may be running without any issues in the editor or even in…
Handling animations in C++
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”!
This post assumes you’re somewhat familiar with the Persona Editor and the following terms: animation sequence, blend spaces and state machines.
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:
1 2 3 4 5 6 7 8 9 10 11 12 |
protected: /*True means that we're currently in air - or falling*/ UPROPERTY(EditAnywhere, BlueprintReadOnly) bool bIsFalling; /*Holds the current speed of our character*/ UPROPERTY(EditAnywhere, BlueprintReadOnly) float MovementSpeed; /*Updates the above properties*/ UFUNCTION(BlueprintCallable, Category = "UpdateAnimationProperties") void UpdateAnimationProperties(); |
When you’re done with that, switch to your source file and add the following implementation of the UpdateAnimationProperties:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void UMyAnimInstance::UpdateAnimationProperties() { //Get the pawn which is affected by our anim instance APawn* Pawn = TryGetPawnOwner(); if (Pawn) { //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:
Then:
- 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.
Very nice article. One quick suggestion from me is instead of calling UpdateAnimationProperties() in Blueprint, you can override the NativeUpdateAnimation in C++ and call UpdateAnimationProperties there. 🙂
You’re definitely right! To be honest, I don’t remember why I didn’t follow your approach.
-Orfeas
How do you do this?
Thank you Orfeas! I was racking my brains out to figure out how to expose variables from C++ to blueprint, and you saved the day! 🙂
I have much more complex AnimInstance/AnimBP. Animations works in the Anim BP (tinkering with the variables) and in the Character BP (an Idle Anim as default), but when I press Play, the character is spawned, but frozen. No Input or HUD like Health bar/Ammo is working (the healthbar is empty and Ammo is 0). Game Mode is set with the Character as a Defaullt Pawn. All worked when it was written with Blueprint nodes, but when I tried to change the BP nodes into C++, all stopped. Is the GameMode should be set in the code?
I’m not sure what’s wrong with your code but when I’m using a custom game mode class I create a blueprint based on my C++ class and assign the Blueprint class as the default mode through the editor (avoid string references at all costs).
-Orfeas
Hi Orfeas,
Thank you for the answer. The problem has been solved. The line: Super::BeginPlay() ; was removed with other code.
Great tutorial (as always) – just a note that you have to include #include “GameFramework/CharacterMovementComponent.h” in your cpp file for the bIsFalling = Pawn->GetMovementComponent()->IsFalling(); part to work.
Great tutorial – so much more elegant than the blueprint driven system. I have found adding extra functionality is so much easier – thanks!
Very cool tutorial but I’m a bit stuck. I can’t find the CPP UpdateAnimationProperties anywhere to add to my event graph, even though the parent class of my new AnimationBlueprint is my custom MyAnimInstance
It compiled fine, and is defined just like you’ve suggested:
UFUNCTION(BlueprintCallable, Category = “UpdateAnimationProperties”)
void UpdateAnimationProperties();
Reading the comments it may be useful to just override NativeUpdateAnimation, which I’ll now research how to do properly as well.
Thanks for all your content!
Never mind, seems to be a quirk with the engine. It didn’t show up until I closed and re-opened the Unreal Engine – this seems to be a widely reported behavior.
Hi!… this is very useful thanks…
I came from Unity long time ago, and in Unity you write the whole logic of your character inside the player class (csharp scripting)… so.. i was wondering if you can do the same in Unreal…
For instance, you create your character class based on ACharacter, lets say AMyCharacter (a common name), and inside AMyCharacter you put the UpdateAnimationProperties function… AMyCharacter::UpdateAnimationProperties()
then, you expose the AMyCharacter::UpdateAnimationProperties() in the animation blueprint as you shown..
Is it possible?