In a project I’m working on, I have Item Objects (UObjects) and a single Item Actor (AActor) that represents Items in the Game World. The Objects have information on the Static Mesh and Materials the Actor should adopt. The Actor has a reference to the object class.
However, I cannot not pull that information from the Object until it’s instantiated, and as far as I know only at runtime in the Actor’s construction or begin play.
Is there a way to perform this action in the construction script of the Actor so that I can see them in the editor while I’m world-building?
Could you provide an example of how I might use that struct in creating an Object? I know its a param in spawning an actor.
My actor’s construction script:
AItemActor::AItemActor()
{
PrimaryActorTick.bCanEverTick = false;
bReplicates = true;
bReplicateUsingRegisteredSubObjectList = true;
//Create Static Mesh for the Item Actor
StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Default Static Mesh"));
ItemData = NewObject<UItemObject>(this, TEXT("ItemData"), RF_NoFlags, ItemClassTemplate);
if (ItemData)
{
auto StaticMeshAsset = ConstructorHelpers::FObjectFinder<UStaticMesh>(*ItemData->ActorStaticMesh.ToSoftObjectPath().ToString());
if (StaticMeshAsset.Object) StaticMesh->SetStaticMesh(StaticMeshAsset.Object);
//Set all materials of static mesh with the supplied array from ItemObj
for (size_t i = 0; i < StaticMesh->GetNumMaterials(); i++)
{
StaticMesh->SetMaterial(i, LoadObject<UMaterialInterface>(NULL, *ItemData->ActorStaticMeshMaterials[i].ToString(), NULL, LOAD_None, NULL));
}
}
}
Unfortunately, I’m also running into an issue where the class is not valid at any point on construction, therefore I cannot create the Item or get its information through GetDefaultObject().
I think the easiest solution would be just to have a DataTable in the Actor of all the Items and their associated meshes and go from there.
The Item Object Class variable (to spawn the Item Object) was being set in the child BP class (in the details panel), therefore it was not accessible yet to the Construction script of the C++ class.
So I moved down the line of functions called and implemented the code to set the Static Mesh from the Item Data during PostInitProperties(), like so:
void AItemActor::PostInitProperties()
{
Super::PostInitProperties();
if (!ItemObject)
{
if (ItemObjectClass.IsValid() || ItemObjectClass.IsPending())
{
//Load Item Object Class Ptr and spawn Item
auto ValidItemClass = ItemObjectClass.LoadSynchronous();
ItemObject = UFunctionLibrary::CreateItemObject(ValidItemClass, ItemCount);
}
}
if (ItemObject && StaticMesh)
{
//Set StaticMesh
if (ItemObject->ItemMesh.IsValid() || ItemObject->ItemMesh.IsPending())
{
UStaticMesh* ItemMesh = ItemObject->ItemMesh.LoadSynchronous();
if (ItemMesh) StaticMesh->SetStaticMesh(ItemMesh);
}
}
}