Why does a c++ blueprint behave differently than a normal blueprint

Hello,

I’ve been struggling with a strange behavior with the blueprints for days. I have no idea how to fix it.

I wanted to create a pawn where you can swap hair and clothes. If I just want to create this with Blueprint it works.

However, if I create the same structure with C++, then the hair mesh goes haywire.

Overall, every mesh goes crazy when I put it under the body. Only the clothing does not seem to be affected.

This is what it looks like when I swap the body mesh and hair mesh

It’s only like that with the C++ class.

headers:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "Test_Pawn_Class.generated.h"

UCLASS()
class TESTPROJECT_API ATest_Pawn_Class : public APawn
{
	GENERATED_BODY()

public:
	// Sets default values for this pawn's properties
	ATest_Pawn_Class();
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

private:
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
	class UCapsuleComponent* CapsuleComp;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
	class USkeletalMeshComponent* Mesh;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
	class USkeletalMeshComponent* Hair;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
	class USkeletalMeshComponent* Cloth;	
};

C++:

// Fill out your copyright notice in the Description page of Project Settings.


#include "Test_Pawn_Class.h"
#include "Components/CapsuleComponent.h"
#include "Engine/SkeletalMesh.h"

// Sets default values
ATest_Pawn_Class::ATest_Pawn_Class()
{
 	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule Collider"));
	RootComponent = CapsuleComp;

	Mesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Body"));
	Mesh->SetupAttachment(RootComponent);

	Hair = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Hair"));
	Hair->SetupAttachment(Mesh);
	Hair->SetMasterPoseComponent(Mesh);

	Cloth = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Cloth"));
	Cloth->SetupAttachment(Mesh);
	Cloth->SetMasterPoseComponent(Mesh);

}

// Called when the game starts or when spawned
void ATest_Pawn_Class::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void ATest_Pawn_Class::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void ATest_Pawn_Class::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

}

Haven’t worked with characters in c++ but I’m noticing your components aren’t showing up on the left side of the details panel.

Try calling RegisterComponent() on them before setupAttachment().

I tried like this

	CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule Collider"));
	RootComponent = CapsuleComp;

	Mesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Body"));
	Mesh->RegisterComponent();
	Mesh->SetupAttachment(RootComponent);

	Hair = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Hair"));
	Hair->RegisterComponent();
	Hair->SetupAttachment(Mesh);
	Hair->SetMasterPoseComponent(Mesh);

	Cloth = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Cloth"));
	Cloth->RegisterComponent();
	Cloth->SetupAttachment(Mesh);
	Cloth->SetMasterPoseComponent(Mesh);

Unfortunately without success. Nothing has changed.

Did a custom test and seems to work fine

.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "TestCharacter.generated.h"

UCLASS()
class BALLROLL_API ATestCharacter : public APawn
{

	GENERATED_BODY()

public:
	// Sets default values for this pawn's properties
	ATestCharacter();
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

private:
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
		class UCapsuleComponent* CapsuleComp;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
		class USkeletalMeshComponent* Mesh;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
		class USkeletalMeshComponent* Hair;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
		class USkeletalMeshComponent* Cloth;

};

.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "TestCharacter.h"
#include "Components/CapsuleComponent.h" 
#include "Components/SkeletalMeshComponent.h" 

// Sets default values
ATestCharacter::ATestCharacter()
{
	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule Collider"));
	SetRootComponent(CapsuleComp);
	
	
	Mesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Body"));	
	Mesh->SetupAttachment(RootComponent);
	

	Hair = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Hair"));
	Hair->SetupAttachment(Mesh);	
	Hair->SetMasterPoseComponent(Mesh, true);

	Cloth = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Cloth"));	
	Cloth->SetupAttachment(Mesh);	
	Cloth->SetMasterPoseComponent(Mesh,true);

}

// Called when the game starts or when spawned
void ATestCharacter::BeginPlay()
{
	Super::BeginPlay();

}

// Called every frame
void ATestCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void ATestCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

}

Working example screenshot

Could it be the fact that you are using the old set root component structure?
Now it is through a method not assigned with =

Oh and swap out the API it was just from an old test project

root component with the method didn’t work either. There is no change to be seen.

In your example you only use have clothing meshes, that always worked for me too. You can see it in the dress.

For whatever reason, the hair mesh and the body mesh don’t work in other skeleton components except the skeleton mesh component “Body”. However, when I use other body meshes or hair meshes, the same thing always happens.

I feel like my project is cursed.

Could it be a different problem? Something stemming from your mesh export / omort into engine?

Is the up axis set on export the same for all of the character parts?

Clearly the c++ side works. Try re-exporting the mesh for tests.

Also check if the hair has all vertices weighted (all need to belong at least to one bone).

If they have zero weights in places it can freak out during animation.

I imported the meshes again and also imported completely fresh ones, the behavior remains the same.

If I just build it as a blueprint and don’t use a C++ class, the meshes behave completely correctly.

What I noticed. The body and hair meshes behaves exactly opposite of the dresses. When I remove the body from the C++ blueprint, the dress lies strangely on the floor.

I also noticed that the dress is always based on the body mesh. It doesn’t matter whether I have the body in Mesh(body) or in Hair(hair). The behavior can be seen on my first screenshots.

The hair mesh always behaves strangely unless it is placed in the mesh(body). Hair(hair) or Dress(dress) makes no difference. The body behaves exactly the same way.

If I remove the body from the pure blueprint, then the clothes and hair remain normal.

For whatever reason, the Mesh(Body) Skeleton Mesh affects the other Skeleton Meches in the blueprint. It also makes no difference if I separate them from the mesh (body) in their herachie.

totally weird.

Could you upload the 3 meshes somewhere to do some tests? There must be some sort of interaction that you are not noticing.

Have you tried setting the collision profiles for the parts?
Capsule = Pawn
Body = CharacterMesh
Hair = CharacterMesh
Cloth = CharacterMesh

You can find the Mshes under this link:

Collision is disabled for each part.

I played around some more using the UE Quinn character. He’s also behaving very strangely.

Quinn in Mesh(Body)

Quinn in Hair(hair)

Something’s broken there.

The character is missing a skeleton for body in the upload. Regenerating it from scratch seems to not work well with other parts.

sorry my mistake I added the skeleton. same link

It definitely stems from Set Master Pose Component. If I set on begin play that the c++ hair gets disconnected by setting Set Master Pose Component to null it goes back to normal.

Looking at the skeletal structure between the hair and body you have messed up bone orientations:
pelvis x axis is pointing in different direction
head x axis is pointing in different direction

The body has x going to the side and y is down???
On the hair x is up axis and y is front for the joints that are in the body (spine,head, pelvis,neck).

This is why your hair is messing up.
Once you set master pose it will match the pelvis, head hence the rotations being misaligned.

You need to re-rig the hair having IDENTICAL oriented bones from the body (in terms the axis need to align)

Probably best to just clone the needed bones from the full rig to the hair and re-link the hair strand bones.