How to load and move skeleton asset in cpp code?

I tried to load SkeletalMesh like this but it returns Null
FString MeshPath = TEXT(“C:/Users/p/Content/Characters/Mannequin_UE4/Meshes/SK_Mannequin_Skeleton.uasset”);

FPaths::FileExists(MeshPath) returns True

but this one returns Null
UObject* BuffCharMesh = StaticLoadObject(USkeletalMesh::StaticClass(), nullptr, *MeshPath);

You can check my repo, if you want to (question is open, still) :

This isn’t working because you’re not really supposed to be loading things by path unless absolutely necessary.

If you plan on having a blueprint subclass of your Character, then just add the following member variable to your header file:

    UPROPERTY(EditAnywhere)
    TObjectPtr<USkeletalMesh> Mesh;

And then you’ll be able to set the mesh in the properties of your character.

1 Like

Hi @ScrewdriverHyena , thank you for answer, but currently everything is ok with mesh loading and issue in how to actually move bones in cpp code I unsuccessfully tried poseblemeshcomponent and control rig (you can’t reparent blueprint of control rig to cpp class) and currently I stopped on AnimInstance but it expects some pose in result and I don’t know which type should be where …

You can check attached GitHub repo for more details if you’re interested (I don’t want to copy-paste a lot of code here), will be great to get any feedback, questions or ideas how to implement that )

Hello, tempdeltavalue. Open your Content Drawer and locate the Skeletal Mesh. Select it, then right-click it; go to “Copy Reference”. This will copy the correct path. Paste it into your code.

Whenever you do this, you will notice that the file name and extension is always “yourAssetNameHere.yourAssetNameHere” instead of “youAssetNameHere.uasset”. I know that uasset is literally the extension when you are looking at your files in Windows Explorer, but that is not how Unreal Engine wants the filename and path.

Function to load and set skeletal mesh on a skeletal mesh component given an asset path. Must be used in constructor.

void SetSkeletalMeshInConstructor(USkeletalMeshComponent* component, FString meshPath)
{
	USkeletalMesh* newMesh = Cast<USkeletalMesh>(StaticLoadObject(USkeletalMesh::StaticClass(), nullptr, *meshPath));
	if (newMesh != nullptr && component != nullptr)
	{
		component->SetSkeletalMesh(newMesh);
	}
	else
	{
		// do your error logging here
	}
}

BTW setting stuff up via paths is perfectly valid. For projects with many dynamically spawned objects and no blueprints its the only sane way to do it. Manually setting stuff up in the editor for everything doesn’t work in that case.

Hard-coding paths is most definitely bad practice. I’m sure there are cases where it’s perfectly valid- but setting the skeletal mesh for your character is not one of them in my opinion.

In cases where I find myself wanting to use a raw path, I generally opt to use a UPrimaryDataAsset with the properties that I need. If I’m working on something with no Blueprint subclass, I simply load the data asset as a property of a game class that I do have a BP subclass of, such as the gamemode or asset manager.

With that said, each to their own, I guess.

@e7t5i_x0z1 @Shmoopy1701 Hi, humans , first of all, thank you for your attention to this issue and your comments :heart_hands:, I will take them into account a little later

But as I mention above currently everything is ok with mesh loading (I just cannot edit original question here :frowning: ) , I got mesh that I set in blueprint using GetMesh()

USkeletalMeshComponent* SkeletalMeshCompt = GetMesh();
if (SkeletalMeshCompt != NULL) {
	UE_LOG(LogTemp, Warning, TEXT("horray!"));

	PoseableMeshComp = CreateDefaultSubobject<UPoseableMeshComponent>(TEXT("PoseableMeshComponent"));

	PoseableMeshComp->AttachToComponent(SkeletalMeshCompt, FAttachmentTransformRules::KeepRelativeTransform);
	PoseableMeshComp->SetSkeletalMesh(SkeletalMeshCompt->SkeletalMesh);
	PoseableMeshComp->SetWorldLocation(SkeletalMeshCompt->GetComponentLocation());
	PoseableMeshComp->SetWorldRotation(SkeletalMeshCompt->GetComponentRotation());
}

and in BeginPlay I do this

if (PoseableMeshComp) {
UE_LOG(LogTemp, Warning, TEXT(“Pose mesh inited”));

	FName boneName = "spine_01";
	//UAnimInstance* animInstance = SkeletalMeshCompt2->GetAnimInstance();

	FTransform boneTransform = PoseableMeshComp->GetBoneTransformByName(boneName, EBoneSpaces::ComponentSpace);
	boneTransform.SetRotation(FQuat::MakeFromEuler(FVector(45.f, 45.f, 45.f)));
	PoseableMeshComp->SetBoneTransformByName(boneName, boneTransform, EBoneSpaces::ComponentSpace);
	//PoseableMeshComponent->UpdateChildTransforms();
	//animInstance->UpdateAnimation(0.f, false);

}

but it does not affect the skeleton in any way (and mesh is not NULL I see “horray” and “Pose mesh inited” in output log), currently I think about AnimInstance but I cant find needed type of pose to pass in some way (which I don’t know) into result from cpp

And in general I want to stay in cpp as much as it possible in context of current “task”

blender