Lyra project integration example

Sample of Ready Player Me Avatars integrated with the UE5.3 Lyra project.

The Lyra example is Unreal Engine only content and may not be used outside of its ecosystem. Ready Player Me is not affiliated with Epic Games.

The sample uses Unreal Engine 5.3 and is not compatible with the older versions

The Lyra Project

Lyra is a full-fledged project demonstrating many of Unreal Engine's features and capabilities. Familiarize yourself with an overview of the project in the Unreal Engine Lyra Sample Game documentation.

Lyra is a learning resource designed as a sample game project to help you understand the frameworks of Unreal Engine 5 (UE5). Learn more about the Lyra project in the Unreal Engine Lyra Sample Game documentation.

Lyra and Ready Player Me avatars

The original Lyra Project uses the UE5 skeleton for gameplay. It contains complex animations, and it uses IK and control rigs that heavily depend on the UE5 skeleton.

By default, the Ready Player Me skeleton is not compatible with UE4 and UE5 skeletons as it contains different bone names and a different hierarchy.

However, it is possible to retarget all the animations and change the control rigs so that the Ready Player Me characters work correctly. This is time-consuming.

Instead, this example demonstrates the following strategy.

  • Animations via runtime IK retargeting.

  • Use an invisible actor to control the character

  • Retarget the animations from this actor to the ReadyPlayerMe avatar.

Download the Ready Player Me sample project

Character

  1. Unzip and open the LyraRpmExample project in Unreal Engine 5.

  2. You may not have the exact same version of UE5. If prompted, rebuild the project. This may take some time.

  3. Inside the Content > Characters folder, if it doesn't exist, create a new folder and call it ReadyPlayerMe.

  4. Inside the Content > Character > Cosmetics folder, find the B_Manny actor blueprint. Along with B_Quinn, these are the characters spawned at runtime in the actual game.

  5. Duplicate B_Manny, rename it to B_RPM and move it to the new ReadyPlayerMe folder.

  6. In the B_RPM actors Details panel, add the ReadyPlayerMe component to load the avatars at runtime.

  7. Select the ReadyPlayerMe component and in the Details panel:

    1. Set the Url shortcode of the avatar

    2. Set the target skeleton to RPM_Mixamo_Skeleton.

    3. [Optional] Add an avatar config. You can use Characters > ReadyPlayerMe > Data > DA_AvatarConfig (Optionally edit the avatar config and set the Texture Atlas to High for fewer draw calls.)

Animation Retargeter

Next, you need an IK Retargeter that will retarget the animations from UE5 Manny to the RPM avatar. For this example, it is provided for you. To learn more about how to create IK Rig and IK Retargeter, check the following example to see how this was done.

  1. Open Characters > ReadyPlayerMe > Rigs > IK_RPM_FullBody.

  2. In the details, notice that it's using the RPM_Mixamo_SkeletalMesh.

  3. Open the Characters > ReadyPlayerMe > Rigs > RTG_UE5Manny_RPM_FullBody IK Retargeter. Notice that its Target IKRig Asset is set to IK_RPM_FullBody.

Lyra's character holds a weapon with both hands. The hands of the Ready Player Me avatar must be in exactly the same position as that driving mannequin's hands. To achieve this, we adjust some settings in the IK Retargeter.

  1. In the Retargeter Details panel, find the Blend to Source property and set it to 1.0 if not already set.

Animation Blueprint

Next, we need an animation blueprint for the Ready Player Me avatar. This example provides you with one.

  1. Open the ReadyPlayerMe > Animations > ABP_RPM_Mannequin_Retarget Animation Blueprint.

  2. In the AnimGraph, create a Retarget Pose From Mesh node and connect it with the Output Pose node. In the example, this is already done for you.

  3. Click on the RetargetPoseFromMesh node, and in the Details panel, verify that Use Attached Parent is checked.

  4. Also, set the IKRetargeterAsset to the RPM_IK_Retargeter that we created: RTG_UE5Manny_RPM_FullBody. In the example, this is already done for you.

Configure Character

  1. Save your work so far if you haven't already.

  2. Open the B_RPM actor again and select its MeshComponent.

  3. In Details, under Animation, set the animation class to the ABP_RPM_Mannequin_Retarget animation blueprint.

  4. Right-click the Skeletal Mesh icon and select Clear.

Setting the Skeletal Mesh to None is important, as runtime changing of the mesh breaks the skeletal mesh component.​

Helper Functions

To implement avatar preloading and saving avatars in the local storage, we need to create a blueprint function library, we'll call it BL_RpmLibrary.

For saving the avatar URL in the local storage, we'll create a SaveGame blueprint and call it B_AvatarSaveGame, it will have a single field AvatarUrl. Next, we'll make a function and call it SaveAvatarUrl, it will remove existing AvatarSaveGame files, create an instance of the B_AvatarSaveGame object, and save it in the local storage.

For loading the saved avatar URL from the local storage, we'll add another function and call it LoadSavedAvatarUrl. It will check if there is an existing AvatarSaveGame in the local storage, and return its avatar URL.

For preloading avatars in the further steps, we'll need to create a function and call it GetAvatarsToPreload. It will return the list of the avatars that would need to be preloaded. This function will add the current player avatar URL to the list of the bot URLs.

Character Selection

Inside the W_LyraFrontend widget, we will add a new button and set the button text to Select Character. Inside the button click event, we will add a logic that will open a new character selection screen.

To make an avatar selection screen we duplicate the already existing W_ExperienceSelection screen and name the new widget W_CharacterSelectionScreen.

We need to change the UI of the character selection widget according to our needs. For the existing buttons, we need to change the implementation of the OnButtonClick event in a way that would select the avatar URL that we hardcode in this UI. To have multiplayer support, we will create two events, one will be executed on the server, the other one on the owning client. We call the SR_CharacterSelected event, which will call the CL_CharacterSelected event. Inside the CL_CharacterSelected event, we will save the avatar URL in the local storage. We will set the replicates property of the SR_CharacterSelected events to Replicated and Run On Server. We will set the replicates property of the CL_CharacterSelected event to Replicated and Run On Owning Client.

For the button images, we will use the RPM render API to download the rendered avatar images and display them on the buttons. We'll create a blueprint class B_AvatarImageApplier that will load the rendered image and apply it to the button.

For the already existing hardcoded avatars we will apply images on view creation. For the custom player avatar that will be created by the avatar creator, we will apply the image on activation, this will keep the player image up-to-date.

We'll add another button next to the existing selection buttons that will open the avatar creator scene.

Avatar Creator

To be able to create an avatar that would be playable in the Lyra game we need to add the custom avatar creator widget to the menu. Check the setup steps in the documentation.

To create the avatar creator widget, we will duplicate the W_ExperienceSelection screen again and name the new widget W_AvatarCreatorScreen. We will adjust the UI of the new widget and add the custom avatar creator widget in the center of the UI. We will wrap the avatar creator widget with the ScaleBox and set the scale to a value between [1-0], this will prevent layout issues and display the avatar creator with the designed layout.

In the properties section of the avatar creator, we need to configure the avatar creator. Find more about the parameters from the documentation.

In the blueprint of the W_AvatarCreatorScreen in the construction event, we need to bind two events to the AvatarCreator widget. We bind Avatar Saved and Avatar Selected events. In both cases, we get the avatar URL and save it in the local storage. In order for this functionality to work in a multiplayer environment we will do the same thing that we've done for the W_CharacterSelectionScreen, we'll add and call SR_AvatarSet and CL_AvatarSet events.

Customize Avatar Creator Environment (Optional)

We can optionally customize the rendering environment and actor of the avatar creator. We can do this without changing the avatar creator.

BP_RPM_PreviewActor actor blueprint is used for rendering the environment of the avatar editor. It inherits from the BI_RPM_PreviewAvatar interface. We will duplicate the BP_RPM_PreviewActor, with some of it's dependencies, and call it BP_RPM_Custom_PreviewActor.

We will change it in a way so that the environment will also be rendered. Afterward, we will attach a gun mesh to the hand of the avatar.

When the actor is ready, we will spawn it in the level and call the OverridePreviewAvatar function of the avatar creator, to override the default actor with the newly spawned one.

If we are using our custom actor we also need to manage the lifecycle of our custom actor.

Spawn Character

Now that we saved the avatar URL in the local storage, we can load an avatar with this URL for our player. In the B_PickRandomCharacter blueprint, we check if the owner is of a type LyraPlayerController, if it is we use the avatar URL that we have saved. If the owner is not LyraPlayerController, then the character is controlled by a bot. For the bots we randomly choose predefined avatar URLs.

We need to spawn the Ready Player Me characters instead of the B_Manny versions. For that in the AddCharacterPart function call we need to change the NewPartPartClass input to B_RPM.

B_PickRandomCharacter blueprint uses FLyraCharacterPart struct to set cosmetic properties of the character part that would be spawned runtime and added to the character. We need to expand it to be able to load an avatar with the URL that we want to use.

To set the avatar URL to the character part that would be added to the player character we need to change the FLyraCharacterPart struct from the C++ code. We need to add a field AvatarUrl to it.

Open the LyraRpmExample\Source\LyraGame\Cosmetics\LyraCharacterPartTypes.h header file. Find the selected chunk of code.

// Compares against another part, ignoring the collision mode
static bool AreEquivalentParts(const FLyraCharacterPart& A, const FLyraCharacterPart& B)
{
	return (A.PartClass == B.PartClass) && (A.SocketName == B.SocketName);
}

Replace it with the following code.

UPROPERTY(EditAnywhere, BlueprintReadWrite)
FString AvatarUrl;

// Compares against another part, ignoring the collision mode
static bool AreEquivalentParts(const FLyraCharacterPart& A, const FLyraCharacterPart& B)
{
	return (A.PartClass == B.PartClass) && (A.SocketName == B.SocketName) && (A.AvatarUrl == B.AvatarUrl);
}

For the next step we will we will add an AvatarUrl field to the ALyraTaggedActor. ALyraTaggedActor is the parent class of the character part(B_RPM) that we will be using to load the avatar. We will add another field, an event OnLoadAvatarPart to this actor, this event will be fired when the AvatarUrl is set, to load the avatar.

Open the LyraRpmExample\Source\LyraGame\AbilitySystem\LyraTaggedActor.h header file. Find the following line of code.

#include "LyraTaggedActor.generated.h"

And add the following line of code below it.

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FLoadAvatarPart);

In the same file find the constructor.

ALyraTaggedActor(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());

And add the following code below it.

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Actor)
FString AvatarUrl;

UPROPERTY(BlueprintAssignable, Category=Actor)
FLoadAvatarPart OnLoadAvatarPart;

To set the AvatarUrl of the LyraTaggedActor, inside the LyraPawnComponent_CharacterParts.cpp file, in FLyraCharacterPartList::SpawnActorForEntry function when the LyraTaggedActor is created we set the AvatarUrl and broadcast the OnLoadAvatarPart event.

Open the LyraRpmExample\Source\LyraGame\Cosmetics\LyraPawnComponent_CharacterParts.cpp source file. Find the following line of code.

if (AActor* SpawnedActor = PartComponent->GetChildActor())
{

And add the following code below it.

if (AActor* SpawnedActor = PartComponent->GetChildActor())
{
	if (ALyraTaggedActor* LyraTaggedActor = Cast<ALyraTaggedActor>(SpawnedActor))
	{
		LyraTaggedActor->AvatarUrl = Entry.Part.AvatarUrl;
		LyraTaggedActor->OnLoadAvatarPart.Broadcast();
}

At the top of the same file find the following line

#include "Cosmetics/LyraPawnComponent_CharacterParts.h"

And add the following line below it.

#include "AbilitySystem/LyraTaggedActor.h"

Loading Avatar

Our B_RPM blueprint inherits the ALyraTaggedActor class that we modified. It should have access to the newly added AvatarUrl and OnLoadAvatarPart properties. In the BeginPlay event, we need to bind an event to the OnLoadAvatarPart event. When the event is fired we check if the UrlShortcode parameter of the ReadyPlayerMe component is empty, and we load a new avatar using the AvatarUrl property. We need to also check and load a new avatar when the BeginPlay is called, this is needed for supporting a multiplayer environment.

Avatar Preloading

To avoid the situation where the game starts with an empty player mesh while the avatar is loading in the background, we should use avatar preloading. We should preload the avatar of our player as well as the avatars of the bots.

There are three places that we need to preload the avatars. W_HostSessionScreen used for hosting a multiplayer or single-player session, W_SessionBrowserEntry used for joining existing multiplayer sessions, and W_ExperienceSelectionScreen used for the quick start. In all of the widgets, we will clean the memory and preload predefined avatars before the PrepareToEnterUserFacingExperience node. This will allow us to have a loading screen while the avatars are loading.

Enable Avatar Caching

Enable Avatar caching from the project settings to get better performance and load avatars faster without the need to download them every time.

Enable the Automatic avatar cache cleaning to prevent having lots of unused avatars in the local storage. You can control the amount of the saved avatars with the CachedAvatarLimit parameter.

Disable Niagara Effects

You can optionally disable the Niagara effects that are applied to the character by disabling the Spawn, Teleport, and Death GameplayCues.

Use Search in Content to find these quickly as they are all over the place.

  • Open the GE_SpawnIn Blueprint and remove Gameplay Cues > Character > Spawn --> This is already done.

  • Open the B_Teleport Blueprint and remove GameplayCue > World > Teleporter > Activate -> This is already done.

  • Open the GA_Hero_Death Blueprint and remove GameplayCue > Character > Death -> This is already done.

Last updated