Problem with FObjectFinder Outside Constructor

So this is my code:

 TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject());
 TSharedRef< TJsonReader<> > JsonReader = TJsonReaderFactory<>::Create(*response->GetContentAsString());
 if (FJsonSerializer::Deserialize(JsonReader, JsonObject)) { 
            FCraftableData craftableData = JsonToCodeableItemMapper::MapAToB(*JsonObject);
            ACharacter* PlayerCharacter = GetOwningPlayer()->GetCharacter();
            ACraftable* CreatedItem = GetWorld()->SpawnActor<ACraftable>(ACraftable::StaticClass(), PlayerCharacter->GetTransform());
            CreatedItem->Initialize(craftableData);
            UE_LOG(LogTemp, Warning, TEXT("Instantiated!"));
        }

ACraftable’s Initialize method:

void ACraftable::Initialize(FCraftableData InputCraftableData)
{
	ACraftable::CraftableData = InputCraftableData;

	FString AssetName = ACraftable::CraftableData.AssetPath;
	FString AssetPathName = "SkeletalMesh'/Game/Models/CreatedItems/" + AssetName + "." + AssetName + "'";
	Super::BeginPlay();
	ACraftable::ItemMesh = ConstructorHelpers::FObjectFinder<USkeletalMesh>(*AssetPathName).Object;

	UE_LOG(LogTemp, Warning, TEXT("%s"), *ACraftable::ItemMesh->GetFullName());
}

I am trying to create an Actor with a varying SkeletalMesh depending on what the HTTP Response is.
The issue here is that FObjectFinder can’t be called outside Constructor, and constructor can’t be sent parameters, as to tell him which is the correct mesh and REST Data.

I need either a way of fetching the mesh outside the constructor, or send parameters to constructor

StaticLoadObject should work, e.g.

Cast<UStaticMesh>(StaticLoadObject(UStaticMesh::StaticClass(), this, *AssetPathName));

I solved it. To anyone in the future getting references to that stupid unexisting wiki page, here’s the answer:

1- Do what everyone recomends, forget about the Constructor option (just create an empty subobject for your mesh), create a method initialize and call it right after your SpawnActor:

ACraftable::ACraftable()
{
...
 	// Set this actor to call Tick() every frame.  You can turn this off to improve 
	ACraftable::ItemMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("MeshComponent"));
	ACraftable::ItemMeshComponent->SetupAttachment(PickupRoot);
...
}

On the Initialize Method you will retreive the Asset from the directory as a StaticLoad. Now be ware that this is actually something everyone suggests against doing. I had to do it because my game absolutely requires it.

void ACraftable::Initialize(FCraftableData InputCraftableData)
{
	ACraftable::CraftableData = InputCraftableData;

	FString AssetName = ACraftable::CraftableData.AssetPath;
	FString AssetPathName = "SkeletalMesh'/Game/Models/CreatedItems/" + AssetName + "." + AssetName + "'";
	Super::BeginPlay();
	ACraftable::ItemMeshComponent->SetSkeletalMesh(Cast<USkeletalMesh>(StaticLoadObject(USkeletalMesh::StaticClass(), NULL, *AssetPathName)));

	UE_LOG(LogTemp, Warning, TEXT("%s"), *Cast<USkeletalMesh>(StaticLoadObject(USkeletalMesh::StaticClass(), NULL, *AssetPathName))->GetFullName());
}

I hope this helped you, and please Epic Games, fix this b#11$#!t!!!

1 Like

Did the trick. My man!