Setting Skeletal Mesh through C++

Partly for practice and partly because I feel that for the current character I am coding it would be beneficial to have it set through code rather than through blueprint, I am trying to set the skeletalmesh and other parts of the skeletalmeshcomponent of my main character through c++ rather than through blueprint. I reckon that by being able to do this, I should be able to use that knowledge for spawning other things through C++ as well. I am still rather new to the whole C++ thing, with my only experience so far being in Unrealscript.


CPP:

static ConstructorHelpers::FObjectFinder<USkeletalMesh> MeshContainer(TEXT("SkeletalMesh'/Game/ThirdPerson/Character/ThirdPersonSkeletalMesh.ThirdPersonSkeletalMesh'"));
	if (MeshContainer.Succeeded())
	{
		PlayerMesh = GetMesh();
		PlayerMesh->SetSkeletalMesh(MeshContainer);
	}	


H:

	UPROPERTY(VisibleAnywhere, Category = SkeletalMesh)
	class USkeletalMesh* MeshContainer;

	UPROPERTY(VisibleAnywhere, Category = SkeletalMesh)
	class USkeletalMeshComponent* PlayerMesh;

If I write it like this, I get the following error;


Error	1	error C2664: 'void USkeletalMeshComponent::SetSkeletalMesh(USkeletalMesh *)' : cannot convert argument 1 from 'ConstructorHelpers::FObjectFinder<USkeletalMesh>' to 'USkeletalMesh *'

I have looked around to find people with similar issues, but I couldn't find anything that addressed my issue or was enough to help me solve it. Doesn't really help either that most topics on that subject are rather old as well, using syntax that has since been deprecated. Can anyone explain what exactly I am doing wrong here?


BP Asset Link

I assume your main character class has a blueprint in the Editor that you are using with game mode to spawn your character.

If you do indeed have a blueprint of the related class, you can just add the asset link in your .h file directly rather than hardcoding the lookup, which can and frequently does fail during packaging.

Step 1:



UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Assets")
USkeletalMesh* AlternateMeshAsset;


then in cpp file

Step 2:
if()pollllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll <~~~ cat on keyboard



if(AlternateMeshAsset)
{
  PlayerMesh->SetSkeletalMesh(AlternateMeshAsset);
}


Step 3:
Then you set the asset ptr in the Editor and you’re done!

I am a huge fan of doing stuff purely in C++, however asset references are one thing I always do via the editor because hardcoded asset references can break during packaging and make it a pain to move/rename c++ referenced assets.

:slight_smile:

Rama

4 Likes

Ah, the breaking part sounds like a pain. I will keep that in mind!

I was actually doing that for the character before I started with trying to set it directly in C++, so if the hardcoding can cause issues, I might as well just stick with my initial code :slight_smile: Thanks!

I removed this line and it works “static ConstructorHelpers::FObjectFinder<USkeletalMesh> MeshContainer(TEXT(“SkeletalMesh’/Game/ThirdPerson/Character/ThirdPersonSkeletalMesh.ThirdPersonSkeletalMesh’”));”

setting skeletalmesh crashes my editor?!

1 Like

Change “PlayerMesh->SetSkeletalMesh(MeshContainer);”
to “PlayerMesh->SetSkeletalMesh(MeshContainer.Object)”

First of all, if your coming from Unity, the equivalent of prefab is bluePrint. Within your bluePrint, there are components you create from the class/bluePrintEditor such as camera, springarm and so, and there are bones of the skeletal mesh which are simply the nodes in Unity terminology.

For instance, if your BluePrint is based on an imported vehicule FBX which is constitued out of wheels, body, dashboards and so, then these elements are referred to as “bones of the vehicle’s skeletal mesh”. To access these bones and rotate/position them individually, then use the piece of code below:

#include "UObject/ConstructorHelpers.h"
#include "Math/Transform.h"
#include "Components/PoseableMeshComponent.h"

AMyPawn::AMyPawn() // the constructor of the blueprint class whose skeletal mesh's bones you want to access and position/rotate
{
// ....
static ConstructorHelpers::FObjectFinder<USkeletalMesh> ActorMesh(TEXT("/Game/path_to_your_skeletalMesh/yourSkeletalMesh.yourSkeletalMesh")); // load the skeletal mesh.

UPoseableMeshComponent* PoseableMesh = CreateDefaultSubobject<UPoseableMeshComponent>(TEXT("name_of_your_choice")); // create a container that will host your skeletalMesh's bones structure and enables you to position/rotate them individually.
PoseableMesh->SetSkeletalMesh(ActorMesh.Object); // Point your container to the skeletalMesh whose bones you want to process and position/rotate.
__int32 numberBones = PoseableMesh->GetNumBOnes();
for(__int32 i = 0; i<numberBones; i++)
{
    FName const BoneName = PoseableMesh->GetBoneName(i);
    FVector location; // initialize them as you wish
    FQuat Rotation;
    FVector Scale;
    FTransform transform(Rotation, location, Scale);
    PoseableMesh->SetBoneTransformByName(BoneName, Transform, EBoneSpaces::WorldSpace);
}
// ...
}