CellTransformer calls RerunConstructionScripts on unregistered actor causes ensure and failed to cook

Because the UWorldPartition::ApplyRuntimeCellsTransformerStack calls RerunConstructionScripts for each actor in the cell,

[Image Removed]

And we have some blueprint actors that move themselves in the UCS, and this causes an ensure then failed on cook.

[Image Removed]

[Image Removed]

<br/>

The questions are:

  1. Is it possible to register those actors first while running the cell transformers?
  2. If #1 is impossible, we may need some methods to filter which actor needs to run CellTransformer before RerunConstructionScripts and any transformer get transformed.
    [Attachment Removed]

Hello!

We did not consider this case in the development of the RCTs. Based on the fact the CS modifies the layout of the actor, it might be best to exclude it from being considered by the RCTs. This can be achieved by adding a tag to the actor “CellTransformer_IgnoreActor”. This would still require to make sure that the components are registered before the CS is rerun:

void UWorldPartition::ApplyRuntimeCellsTransformerStack(ULevel* InLevel)
{
	if (!RuntimeCellsTransformerStack.IsEmpty())
	{
 
...
 
		// Rerun construction scripts for actors in levels before executing the cell transformers, as the Blueprint parent classes might have changed 
		// and we want to make sure the constructed actors are up to date.
		TArray<TObjectPtr<AActor>> LevelActors;
		Algo::CopyIf(InLevel->Actors, LevelActors, [](AActor* InActor)
		{
			return IsValid(InActor) && !InActor->IsChildActor();
		});
	
		for (TObjectPtr<AActor>& LevelActor : LevelActors)
		{
			// Deal with deleted child actors that might have been deleted from previous calls to RerunConstructionScripts
			if (IsValid(LevelActor))
			{
				LevelActor->RegisterAllComponents();
			}
		}
 
		for (TObjectPtr<AActor>& LevelActor : LevelActors)
		{
			// Deal with deleted child actors that might have been deleted from previous calls to RerunConstructionScripts
			if (IsValid(LevelActor))
			{
				LevelActor->RerunConstructionScripts();
			}
		}
 
		ApplyTransformPhase([](const FRuntimeCellTransformerInstance& TransformerInstance, ULevel* Level) { TransformerInstance.PreTransform(Level); });
		ApplyTransformPhase([](const FRuntimeCellTransformerInstance& TransformerInstance, ULevel* Level) { TransformerInstance.Transform(Level); });
		ApplyTransformPhase([](const FRuntimeCellTransformerInstance& TransformerInstance, ULevel* Level) { TransformerInstance.PostTransform(Level); });
	}
}

This has to be done in 2 phases to preserve the attachments between of Components\Actors when the CS is rerun.

That being said, you should look a the current state of the RCT code. We fixed multiple bugs since the 5.6 release. You should look at the following changes as a minimum if you want to keep on using them in version 5.6:

  • 44081791 & 45834203: Fixes parenting issues. This one might not be needed if you register the components as the hierarchy will be repaired in RerunConstructionScript
  • 48817083: addresses a problem with BP actors that are not fully transformed which results in duplicated instances.

If you plan on using FastGeo, I would strongly recommend you consider upgrading to version 5.8 when it releases. We addressed concurrency problem at the FSimpleStreamableAssetManager level.

Regards,

Martin

[Attachment Removed]

I think the problems you ran into are part of the reasons the engine team preferred developing the code that fixes the parenting instead of registering the components. I suggested registering as we are aware of other licensees that have done it. They must have also dealt with the extra problems.

[Attachment Removed]

Hi Martin, thanks for the answers!

I just tried to add the RegisterAllComponents before RerunConstructionScripts, but I found this will cause the render state and physics state not get created while PIE as the FScene and FPhysScene are not created yet at this time.

So I tried to UnregisterAllComponents after RerunConstructionScripts, then all the components will get registered again as usual after the FScene and FPhysScene were created.

And this works well in the editor, I will test this in the packaged game later.

[Image Removed]​

We have also encountered the parenting issues, and I tried 44081791 earlier, it does solve the parenting issue.

But after I add RegisterAllComponents and UnregisterAllComponents, the parenting issues are gone as well. So I decide to leave the changes from 44081791 & 45834203.

However we will upgrade to 5.7 soon, and I don’t wanna get too far away from the latest vanilla engine, so I need to know whether the ​RegisterAllComponents & UnregisterAllComponents a great solution replacement to 44081791 & 45834203 or not?

[Attachment Removed]

I found another issue if RegisterAllComponents here, there are some unrelated components which assume some subsystems are existing on register which lead to crash.

So there still need a pre-filter mechanism, maybe let the transformers do a pre-filter before RegisterAllComponents/RerunConstructionScripts.

[Image Removed]

[Attachment Removed]