InventoryAssembling Meshes
Last modified: 02 December 2024When working with multiple Equipment Meshes representing wearable items, such as armor, it's common to use multiple skeletal meshes that need to follow the same animation.
Unreal Engine offers a few different approaches to deal with this requirement, such as the Leader Pose Component and Skeletal Mesh Merging.
Leader Pose Component
The default strategy used by the Inventory System is the Leader Pose Component. It allows you to configure a leader pose that will have an Animation Instance Blueprint, and other meshes that will follow its animation.
So let's say that your character is composed of multiple meshes, representing the head, torso, pants, gloves, etc. You need to define which one would be the Leader Pose. That's usually the head or a full body mesh, if you are using it.
The Leader Pose should be configured with the following settings:
Setting | Value |
---|---|
| Always Tick Pose And Refresh Bones |
|
|
From there, you need to configure all other Skeletal Mesh Components to follow the leader pose.
Header:
public:
APluginLabsCharacter(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
private:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Components", meta = (AllowPrivateAccess = true))
TObjectPtr<USkeletalMeshComponent> Head;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Components", meta = (AllowPrivateAccess = true))
TObjectPtr<USkeletalMeshComponent> Helm;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Components", meta = (AllowPrivateAccess = true))
TObjectPtr<USkeletalMeshComponent> Chest;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Components", meta = (AllowPrivateAccess = true))
TObjectPtr<USkeletalMeshComponent> Bracers;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Components", meta = (AllowPrivateAccess = true))
TObjectPtr<USkeletalMeshComponent> Legs;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Components", meta = (AllowPrivateAccess = true))
TObjectPtr<USkeletalMeshComponent> Boots;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Components", meta = (AllowPrivateAccess = true))
TObjectPtr<USkeletalMeshComponent> Hands;
/** Support function to create follower meshes IN THE CONSTRUCTOR. */
USkeletalMeshComponent* CreateFollowerMesh(USkeletalMeshComponent* LeaderMesh, FName MeshName, FGameplayTag SlotTag);
Implementation:
APluginLabsCharacter::APluginLabsCharacter(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
GetMesh()->VisibilityBasedAnimTickOption = EVisibilityBasedAnimTickOption::AlwaysTickPoseAndRefreshBones;
GetMesh()->bLightAttachmentsAsGroup = true;
Head = CreateFollowerMesh(Head, "Head", Tag_Crucible_Slot_Head);
Helm = CreateFollowerMesh(Head, "Helm", Tag_Crucible_Slot_Helm);
Chest = CreateFollowerMesh(Head, "Chest", Tag_Crucible_Slot_Chest);
Bracers = CreateFollowerMesh(Head, "Bracers", Tag_Crucible_Slot_Bracers);
Legs = CreateFollowerMesh(Head, "Legs", Tag_Crucible_Slot_Legs);
Boots = CreateFollowerMesh(Head, "Boots", Tag_Crucible_Slot_Boots);
Hands = CreateFollowerMesh(Head, "Hands", Tag_Crucible_Slot_Hands);
}
USkeletalMeshComponent* APluginLabsCharacter::CreateFollowerMesh(USkeletalMeshComponent* LeaderMesh, FName MeshName, FGameplayTag SlotTag)
{
USkeletalMeshComponent* FollowerMesh = CreateDefaultSubobject<USkeletalMeshComponent>(MeshName);
FollowerMesh->bUseBoundsFromLeaderPoseComponent = true;
FollowerMesh->bUseAttachParentBound = true;
FollowerMesh->bLightAttachmentsAsGroup = false;
FollowerMesh->bComponentUseFixedSkelBounds = false;
FollowerMesh->ComponentTags.Add(SlotTag.GetTagName());
FollowerMesh->SetLeaderPoseComponent(LeaderMesh);
FollowerMesh->SetupAttachment(LeaderMesh);
return FollowerMesh;
}
warning
Collisions and Follower Meshes
Follower meshes won't have their physical assets receiving collisions. You either need an invisible full body mesh that can handle collisions or specific collision volumes assigned to the body!