What are the pieces of a character in Unreal Engine?
As mentioned in the Game Mode / Game State section, the Unreal Engine Gameplay Framework helps in understanding how characters work in Unreal Engine. Conceptually, a player consists of a pawn representing the physical presence in the game world, and a controller determines the behavior. This decoupling is useful for AI as well as network replication. For reference, the hierarchy looks like this:
Let’s start with importing the assets, creating the pawn, and working up to the player controller. For Parrot, our player-controlled hero will be Captain Barbarossa (visit the Quaternius website to get the Pirate Kit provided by Quaternius).
Importing Art Assets
In a 3D modeling tool of your choice, export your mesh/animations to an engine compatible format. In this case, the developers used .fbx. Barbarossa’s assets are under Content/Assets/Quaternius/PirateKit/Characters/Barbarossa. You can import your .fbx by right clicking the context menu or dragging and dropping it into the content browser. You’ll be met with an .fbx import settings window. Choose the appropriate options for your import. In this case, be sure that no existing skeleton is selected and that import animations is ticked. Also necessary is creating a new atlas material that can be indexed by your mesh. This material can be reused across assets in the Pirate Kit. You should now have these 3 files and any animations included in your .fbx.
For cleanliness, Animation Sequence files are located underneath the Animations folder adjacent to the 3 files:
Skeleton, Skeletal Mesh, and Physics Assets
A Skeleton is a hierarchy that is used to define Bones (sometimes called joints) in a Skeletal Mesh. These bones should match the rig in your 3D modeling tool. Skeletons can be reused across Skeletal Meshes so long as the rigs are compatible. You will also notice a created Physics Asset. Physics Assets define the physics and collision used by a Skeletal Mesh. They contain rigid bodies and constraints for simulation. You can only have one Physics Asset per Skeletal Mesh and they can conditionally be toggled on or off. You can adjust Physics Assets as they’re imported or create new assets from a skeletal mesh.
Animation Blueprint
Now that there is a Skeletal Mesh to work with, you can start animating it with the Animation Blueprint. The Animation Blueprint is similar to Unity’s Mecanim Animation System. The Animation Graph in Animation Blueprints should look familiar and function in a similar way. Both systems have conditional logic flow that can transition animation states to a final output pose. In your folder, create a new Animation Blueprint from the context menu and select your Skeleton. Our Animation Blueprint will be called ABP_Captain_Barbarossa under Content/Blueprints/Player.
On the left hand side of the Blueprint Inspector, you’ll notice there are two graphs: Event Graph and Animation Graph. The Animation Graph is the state machine that controls your final output pose. The Event Graph is where you can define any logic related to Animation. Unlike Unity, where you need to pass data to the Mecanim component, Animation Blueprints can pull what they need on a given event. For example, you might want to query the character’s velocity and drive your animation based on that value. A clean way to do this is to use the Event Blueprint Initialize Animation Node in the Event Graph, Get the Owning Actor, and cache their movement component in a variable. From there, every tick of BlueprintThreadSafeUpdateAnimation, you can query velocity right from your movement component. Variables can also be shared between the Event Graph and Animation Graph.
The configured Animation Blueprint for Barbarossa is worth exploring further on your own. By double clicking into nodes you can see how the state machines, states, and state rules are configured for the final output pose. There are also examples of using a sequence player and using a blend space. Similarly, the event graph shows how the animation is driven by character data - this relationship will become more clear as this article continues.
Pawn
Now that there is a Skeletal Mesh that can animate, you can begin creating your Pawn that will be used by the Game Mode. The developers chose to build on Unreal Engine's default Character which is a child class of the default Pawn C++ class. The Character class has a Character Movement component which is especially useful for this game and is another class to be built on.
Both the player and enemy pawns have some shared functionality such as hitpoints, getting hit, and death. This functionality is shared by creating a AParrotCharacterBase C++ class which inherits from ACharacter. This class provides a good baseline to build from as enemy and player pawns diverge in behavior.
Next, create a AParrotPlayerCharacter C++ to handle player specific logic. Lastly, you will create a blueprint to handle the visual representation of your character. Parrot's Blueprint is BP_ParrotPlayerCharacter under Content/Blueprints/Player. The inheritance hierarchy looks like this:
Opening up BP_ParrotPlayerCharacter, you should see some components under the component inspector on the left of the editor window. The Mesh Component is where you can set your Skeletal Mesh Asset as well as the Animation Blueprint under Anim Class. If the mesh is not positioned correctly, you can adjust the transform values to align with your capsule component. You should have something like this:
Next, you can assign the default pawn class to the Blueprint in the game mode asset.
Now there is an animating pawn that can be used in the game!
Player Controller
With a usable pawn, you can now create the player controller. Player controllers essentially represent the human player’s will. Something to consider when making your game is where to define input events. For simple games where pawns do not change, the pawn is suitable for this. However, when behavior starts to get complex, the player controller is a better option for this. Pawns are transient and can be possessed or unpossessed by player controllers. Pawns can be spawned or destroyed while player controllers persist throughout the game.
You won’t need any C++ logic in the player controller, so just create a blueprint to do what is needed. BP_ParrotPlayerController is located under Content/Blueprints/Player. The inheritance hierarchy looks like this:
Inside the Blueprint, notice there are input event nodes that lead to some basic gameplay logic. These input events are specifically related to Enhanced Input. You can learn more about how that is configured in the Enhanced Input documentation. Caching the Parrot Player Character Pawn on Begin Play, we can use that to call base movement functions later. Such as Add Movement Input, Jump, and StopJump.
Time to test! In the Game Mode BP, set the new player controller class and then verify you can use the controller in game:
From this drop down in the level editor, verify that the right game mode is selected:
Lastly, make sure that your map has a PlayerStart actor and a camera you can view. When you hit the play button you should see your character moving around and animating:
Parrot Character Movement Component
The base ACharacter class has a lot of great functionality built-in. An example of this is the UCharacterMovement actor component. The character movement component handles all logic for how a character moves through the world. It supports walking, running, falling, swimming, flying, and custom movement modes. It is definitely worth exploring on your own to get an idea of how basic character movement works and to also get an idea of how powerful actor components are.
For Parrot, the base character movement component did not provide the game feel that the developers were looking for out of the box. However, it did provide a solid foundation to build on. The UParrotCharacterMovementComponent C++ class derives from UCharacterMovementComponent. We then can set the movement component on the CDO movement component in BP_ParrotPlayerCharacter like so:
But what does the Parrot Movement Component actually do? In essence, the component allows you to define a ‘platformer style’ jump by overriding functions from the base movement component related to jumping. Using some design-tunable values, when a jump occurs, you can modify the player character’s gravity scale and jump velocity to reach an apex height in a fixed amount of time. Upon reaching the apex, you can then start to apply a falling gravity scale. If the player releases the jump input early, you can apply a multiplier to scale the gravity up.
The result is a jump that ‘feels’ more like what you’d expect in a platformer, as opposed to just applying an impulse on the Z-axis.
Leaning on the heavy lifting of the base character movement component, you can just focus the Parrot movement component logic on the jump. The values in the inspector for BP_ParrotPlayerCharacter on the movement component are also worth looking at to get a full picture of how all the pieces of the movement component work together. The movement logic can be expanded to fit any variety of use cases.