Alternatives to FObjectFinder for loading Static Meshes at runtime?

I have a static mesh component attached to my character, which I would like to change the mesh of dynamically at runtime.

I would like to use StaticMeshcomp->SetStaticMesh(MeshAsset);

But this only works if MeshAsset is set properly, and the only way I have found so far to do this is using ConstructorHelpers::FObjectFinder. This function however only works in a constructor, but I would like this to run in a standalone function that I can call at runtime.

Below is a simplified version of the code I have so far:

void MyCharacter::SetMesh(FString MeshReferenceLocation)
{
	static ConstructorHelpers::FObjectFinder<UStaticMesh> MeshAsset(MeshReferenceLocation); // Cannot run unless in a constructor
	if (!MeshAsset.Object)
	{
		UE_LOG(LogTemp, Error, TEXT("Could not find mesh asset reference."))
		return;
	}
	UStaticMesh* StaticMeshReference = MeshAsset.Object;
		
	MyStaticMeshComponent->SetStaticMesh(StaticMeshReference);
}

Are there any straightforward methods of me loading the StaticMesh asset at runtime using a reference path?

I don’t want to create an object which loads all of my (potentially hundreds) of possible Static Meshes in a constructor when I will only ever need one at a time, as I am worried about the performance issues.

UPROPERTY(EditAnywhere)
TSoftObjectPtr<UStaticMesh> MeshAsset;

UStaticMesh* Mesh = MeshAsset.LoadSynchronous();

FSoftObjectPtr is a type of weak pointer to a UObject, that also keeps track of the path to the object on disk. It will change back and forth between being Valid and Pending as the referenced object loads or unloads. It has no impact on if the object is garbage collected or not.

This is useful to specify assets that you may want to asynchronously load on demand.

TSoftObjectPtr is a template wrapper around that so you don’t have to cast things yourself. i.e. LoadSynchronous is just, call the non-template one then cast to T:

/** Synchronously load (if necessary) and return the asset object represented by this asset ptr */
T* LoadSynchronous() const
{
    UObject* Asset = SoftObjectPtr.LoadSynchronous();
    return Cast<T>(Asset);
}

Privacy & Terms