C++ Shipped Version: Create Actors at Runtime doesn't show in the App but in Editor mode yes.

Bug Report: Runtime Actor Creation Issue in Unreal Engine 5.3.2

Description:
There is a bug affecting the creation of Actors with Mesh components at runtime in Unreal Engine 5.3.2. This issue only occurs in the Packaged version of the project. The same functionality works perfectly in the Editor.

Details:
The issue arises when using C++ code to dynamically create and configure Actors during runtime. Specifically:

  • I have an ExternalCommunicationManager that is responsible for creating drawable entities.
  • These entities are selected based on a category provided by external input.
  • The system assigns an appropriate Mesh and materials to the Actor based on this category.

In the Editor version, this process works as intended, and the Actors are created and rendered correctly. However, in the Packaged version of the project, the Mesh components fail to display and seems not in the game.
I added some UE_LOG to trace everithing in the packaged version of the App and seems that the execution goes into it.

Steps to Reproduce:

  1. Use C++ to implement an Actor creation system at runtime.
  2. Assign Mesh components and materials to the Actors based on an external category.
  3. Run the project in the Editor – the Actors are created and rendered correctly.
  4. Package the project and run the executable – the issue with the Actors occurs.

Expected Behavior:
The Actors should be created with their Mesh components and materials correctly assigned and displayed, both in the Editor and in the Packaged version of the project.

Actual Behavior:
In the Packaged version, the Actors are not displayed as expected, indicating that the Mesh components or materials are not being set up properly.

Additional Notes:

  • This issue seems specific to the runtime behavior in the Packaged version.
  • There are no errors or warnings during the packaging process or runtime.
  • The Meshes and materials are properly referenced and loaded in the Editor.

Environment:

  • Unreal Engine Version: 5.3.2
  • Platform: Windows 11 (Packaged build)

Some code of my class that i’m currently using.

void  AExternalCommunicationManager::instanceDrawableEntity(ADrawableEntity* elem) {
    UStaticMesh ** mesh = staticMeshesTable.Find(elem->category);  //UStaticMeshComponent **scene_meshComponent = meshLookUpTable.Find(elem->category);
    // TODO: to add the "debug label".
    //need to create the Actor into the game
    FString id_actor = FString::FromInt(elem->tracking_id);
    FName name_in_game = FName(*id_actor);//elem->tracking_id+"";// + " Actor";
    AUActorDrawable* new_object = ref_to_world->SpawnActor<AUActorDrawable>(AUActorDrawable::StaticClass(), FVector::ZeroVector, FRotator::ZeroRotator);
    new_object->Tags.Add(FName(*id_actor));
    #if WITH_EDITOR
        new_object->SetActorLabel(name_in_game.ToString());
    #else
    #endif

    if (!mesh)
    {
        // Not implemented model:
        //elem->MeshComponent = NewObject<UStaticMeshComponent>(elem->MeshActorInGame->GetRootComponent(), "SMComp_Ale_NotImpModel", EObjectFlags::RF_Public); //*meshLookUpTable.Find(managerSmooth->c_exclamation_mark_ERRORS)
        mesh = staticMeshesTable.Find(this->c_exclamation_mark_ERRORS);
       // elem->MeshComponent->SetStaticMesh((*meshLookUpTable.Find(managerSmooth->c_exclamation_mark_ERRORS))->GetStaticMesh());
        UE_LOG(LogTemp, Warning, TEXT("ALLERT, an object arrived without the correct C_Category!!! (Arrived  %d  for composed_id: %d"), elem->category,elem->tracking_id);
    }

    FName name_mesh = FName("Mesh " + id_actor);

    UMaterialInstanceDynamic ** fadeMatr = MaterialMeshesTable.Find(elem->category);
    if (!fadeMatr)
    {
        // Not Implemented Material
        fadeMatr = MaterialMeshesTable.Find(this->c_exclamation_mark_ERRORS);
    }

    if(fadeMatr)
    {
        new_object->instanceMeshAndGeorefAndOthers(*mesh,cesium_georeference_actor,name_mesh, *fadeMatr);
        UE_LOG(LogTemp, Warning, TEXT("Instance MeshAndGeorefAndOthers with fade matr | cat: %d  for composed_id: %d"), elem->category, elem->tracking_id);
    }
    else 
    {
        new_object->instanceMeshAndGeorefAndOthers(*mesh, cesium_georeference_actor, name_mesh, NULL);
        UE_LOG(LogTemp, Warning, TEXT("Instance MeshAndGeorefAndOthers without fade matr | cat: %d  for composed_id: %d"), elem->category, elem->tracking_id);
    }
    //NewObject<UStaticMesh>(elem->MeshActorInGame,UStaticMesh::StaticClass(), "Mesh", RF_Public | RF_ArchetypeObject | RF_Transactional, *mesh,true);// NewObject<UStaticMesh>(elem->MeshActorInGame, *mesh, "StaticMesh", RF_NoFlags, *mesh, true, nullptr, true);//
    
    //elem->MeshComponent->GetStaticMesh() = static_Mesh;
    //elem->MeshComponent->SetStaticMesh(static_Mesh);
    elem->MeshComponent = new_object->MeshComponent;
    if (!new_object->MeshComponent->GetStaticMesh())
    {
        UE_LOG(LogTemp, Warning, TEXT("Tried to set the created static mesh, but nope."));

    }

    elem->CesiumGlobeAnchor_var = new_object->CesiumGlobeAnchor_var;
    elem->ActorInGame = new_object;
    elem->can_use_every_objects = true;
    ActorsInGameDrawableEntity.Add(new_object);
    UE_LOG(LogTemp, Warning, TEXT("ExternalCommManager MeshAndGeorefAndOthers being added to ActorsInGameDrawableEntity | cat: %d  for composed_id: %d"), elem->category, elem->tracking_id);

The instanceMeshAndGeorefAndOthers() method:

void AUActorDrawable::instanceMeshAndGeorefAndOthers(UStaticMesh* Mesh, ACesiumGeoreference* cesium_georeference_act,FName name_mesh, UMaterialInterface* matr)
{

	if (Mesh != NULL)
	{
		UStaticMesh * mesh_instance = DuplicateObject<UStaticMesh>(Mesh, this, name_mesh);
		this->MeshComponent->SetStaticMesh(mesh_instance);
		this->MeshComponent->SetVisibility(true);
		//this->MeshComponent->RegisterComponent();
	}
	if (cesium_georeference_act != NULL)
	{
		...
		...
                ...
		if (matr != NULL)
		{
			this->fade_material = DuplicateObject<UMaterialInterface>(matr, this, "fade_material"); //TO TEST
			MaterialInstance = Cast<UMaterialInstanceDynamic>(this->fade_material);

		}
	}
}

// Called when the game starts or when spawned
void AUActorDrawable::BeginPlay()
{
	Super::BeginPlay();
	// attach each single component to this one.
	if (RootComponent != MeshComponent)
		RootComponent = MeshComponent;
}

// Called every frame
void AUActorDrawable::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

Could you please help me? I have been struggling for days to figure out the issue on my own, but it seems to be a problem with the Engine itself.

No one can help me about this problem?

I ported the project from UE 5.3 to UE 5.4.4 and the errors still the same.

Anyone?

After a first developer feedback, i’m re-writing the post to improve the redingness.

Description:
There is a bug affecting the creation of Actors with Mesh components at runtime in Unreal Engine 5.3.2. This issue only occurs in the Packaged Project version (set in DebugGame). The same functionality works perfectly in the Editor.

Details:
The issue arises when using C++ code to dynamically create and configure Actors during runtime. Specifically:

  • I have an ExternalCommunicationManager that is responsible for creating the internal elements of a class called UActorDrawable by calling the instanceMeshAndGeorefAndOthers(...) fuction with one UStaticMesh, georef stuff (CesiumGeoref) and a material (UMaterialInterface).
// Sets default values
AUActorDrawable::AUActorDrawable()
{
	PrimaryActorTick.bCanEverTick = false;
	this->MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMeshComponent"));
	MeshComponent->SetMobility(EComponentMobility::Movable);
	RootComponent = this->MeshComponent; // Set the component as RootComponent
	CesiumGlobeAnchor_var = CreateDefaultSubobject<UCesiumGlobeAnchorComponent>(TEXT("CesiumGlobeAnchor_Ale"));
}

void AUActorDrawable::instanceMeshAndGeorefAndOthers(UStaticMesh* Mesh, ACesiumGeoreference* cesium_georeference_act,FName name_mesh, UMaterialInterface* matr)
{

	if (Mesh != NULL)
	{
		UStaticMesh * mesh_instance = DuplicateObject<UStaticMesh>(Mesh, this, name_mesh);
		this->MeshComponent->SetStaticMesh(mesh_instance);
		this->MeshComponent->SetVisibility(true);
	}
	if (cesium_georeference_act != NULL)
	{
		...
		...
                ...
		if (matr != NULL)
		{
			this->fade_material = DuplicateObject<UMaterialInterface>(matr, this, "fade_material");
			MaterialInstance = Cast<UMaterialInstanceDynamic>(this->fade_material);

		}
	}
}

// Called when the game starts or when spawned
void AUActorDrawable::BeginPlay()
{
	Super::BeginPlay();
	if (RootComponent != MeshComponent)
		RootComponent = MeshComponent;
}

void AUActorDrawable::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}
  • These entities are selected based on a category provided by external input.
  • The system assigns an appropriate Mesh and materials to this Actor based on the arrived category.

In the Editor version:
this process works as intended, and the Actors are created and rendered correctly.
However, in the “Packaged Project” that can be used without the editor, the Mesh components fail to display and seems not in the game.

I added some UE_LOG to trace everithing in the packaged version of the App and seems that the execution goes into it.

Steps to Reproduce:

  1. Use C++ to implement an Actor creation system at runtime.
  2. Assign Mesh components and materials to the Actors based on an external category.
  3. Run the project in the Editor – the Actors are created and rendered correctly.
  4. The “Package Project” executable have the issues that the Actors weren’t display the relative Mesh.

Expected Behavior:
In the “Package Project” version, the Actors should be created with their Mesh components and materials correctly assigned and displayed, both in the Editor and in the “Package Project” version of the project.

Actual Behavior:
In the Packaged version, the Actors are not displayed as expected, indicating that the Mesh components or materials are not being set up properly.

Additional Notes:

  • This issue seems specific to the runtime behavior in the Packaged version.
  • There are no errors or warnings during the packaging process or runtime.
  • The Meshes and materials are properly referenced and loaded in the Editor and visible during execution.

Environment:

  • Unreal Engine Version: 5.3.2 , also tested in 5.4.4 and the same issue
  • Platform: Windows 11 (Packaged build)

Some code of my AExternalCommunicationManager class that i’m currently using.

void  AExternalCommunicationManager::instanceDrawableEntity(ADrawableEntity* elem) {
    UStaticMesh ** mesh = staticMeshesTable.Find(elem->category);
    ...  
  FName name_in_game = FName(*id_actor);
    AUActorDrawable* new_object = ref_to_world->SpawnActor<AUActorDrawable>(AUActorDrawable::StaticClass(), FVector::ZeroVector, FRotator::ZeroRotator);
    new_object->Tags.Add(FName(*id_actor));
    
    #if WITH_EDITOR
        new_object->SetActorLabel(name_in_game.ToString());
    #endif

    // Check if the Mesh for the correct category has been set up.
    if (!mesh) {
        mesh = staticMeshesTable.Find(this->c_exclamation_mark_ERRORS);
        UE_LOG(LogTemp, Warning, TEXT("ALLERT, an object arrived without the correct C_Category!!! (Arrived  %d  for composed_id: %d"), elem->category, elem->tracking_id);
    }

    FName name_mesh = FName("Mesh " + id_actor);
    UMaterialInstanceDynamic ** fadeMatr = MaterialMeshesTable.Find(elem->category);
    
    if (!fadeMatr) {
        fadeMatr = MaterialMeshesTable.Find(this->c_exclamation_mark_ERRORS);
    }

    if(fadeMatr) {
        new_object->instanceMeshAndGeorefAndOthers(*mesh, cesium_georeference_actor, name_mesh, *fadeMatr);
        UE_LOG(LogTemp, Warning, TEXT("Instance MeshAndGeorefAndOthers with fade matr | cat: %d  for composed_id: %d"), elem->category, elem->tracking_id);
    } else {
        new_object->instanceMeshAndGeorefAndOthers(*mesh, cesium_georeference_actor, name_mesh, NULL);
        UE_LOG(LogTemp, Warning, TEXT("Instance MeshAndGeorefAndOthers without fade matr | cat: %d  for composed_id: %d"), elem->category, elem->tracking_id);
    }
    
    elem->MeshComponent = new_object->MeshComponent;
    if (!new_object->MeshComponent->GetStaticMesh()) {
        UE_LOG(LogTemp, Warning, TEXT("Tried to set the created static mesh, but was not possible."));
    }

    elem->CesiumGlobeAnchor_var = new_object->CesiumGlobeAnchor_var;
    elem->ActorInGame = new_object;
    elem->can_use_every_objects = true;
    ActorsInGameDrawableEntity.Add(new_object);
    UE_LOG(LogTemp, Warning, TEXT("ExternalCommManager MeshAndGeorefAndOthers being added to ActorsInGameDrawableEntity | cat: %d  for composed_id: %d"), elem->category, elem->tracking_id);
}

void AUActorDrawable::instanceMeshAndGeorefAndOthers(UStaticMesh* Mesh, ACesiumGeoreference* cesium_georeference_act,FName name_mesh, UMaterialInterface* matr)
{

	if (Mesh != NULL)
	{
		//UStaticMesh * mesh_instance = DuplicateObject<UStaticMesh>(Mesh, this, name_mesh);
		//UStaticMeshComponent* mesh_instance = NewObject<UStaticMeshComponent>(Mesh);

		this->MeshComponent->SetStaticMesh(Mesh);

The problem:
By using DuplicateObject<…>(…), the feature is not kept in the Package Version of the project.

Instead, you must use the SetStaticMesh with the reference of the Mesh that you want to instance (it also improve performance because it is used on GPU as instance of the same object and cached).

But i think that DuplicateObject<…>(…) this have a BUG.