5.8 Bug: broken Blueprint actor attachment hierarchies in World Partition levels using Cell Transformers

When two Blueprint actors with SCS root components are part of an attachment hierarchy in a world partition level using cell transformers, we observe that the child actor becomes detached from the parent actor in a packaged build, or when that level is streamed in during PIE.

We trace the issue back to UWorldPartition::ApplyRuntimeCellsTransformerStack calling AActor::RerunConstructionScripts.

A change was made in 5.8 (CL 50669491) to AActor::DestroyConstructedComponents, which means that the destroyed component’s Outer is now set to something other than its owning actor, which causes OwnerPrivate to become null in UActorComponent::PostRename.

This ultimately breaks the reattachment step later in RerunConstructionScripts. if(Parent) fails because the earlier call to RootComponent->GetAttachParent()->GetOwner() returns null.

We have locally fixed the attachment issue by simply undoing the change from CL 50669491.

Please could you confirm the most appropriate fix for us?

We see that the original CL mentions this resolves issues with Mover, which we are not using. We did consider an alternative fix using Component->GetOuter() instead of GetTransientOuterForRename(Component->GetClass()). Here’s the description from 50669491:

"Fix for crash that can occur when you edit properties via editor Details panel on an Actor using a MoverComponent during play.

The crash was occurring because the component was attempting to reinitialize something that had already been initialized.

Additionally, an assert was being hit when when using the network physics liaison due to it being marked a “Within = MoverComponent” This assert was due to the component being renamed when being destroyed to a name that did not include that it was indeed within the mover component. This appears to be a long standing bug in ActorConstruction.cpp that only really matters in the case when the component being destroyed is Within another component rather than the actor that is being destroyed.. This change makes it so it gets the component’s outer rather than assuming that the outer is the Actor and uses that for the rename"

Hello!

Thanks for the detailed report. The call to RerunConstructionScripts prior to running the RuntimeCellTransformer was added to address issues with BP instances still referencing the components. As you found out, the change to DestroyConstructedComponent broke the reinstanciation flow and left the Child actors without the outdated attachment information. This outdated information was used to remap the references (CombinedReplacementMap).

After discussion with engine team members, it appears that best solution for 5.8 is to restore the old behavior of DestroyConstructedComponent as you already tried. The class that was causing the assert does not exist in 5.8 so we don’t expect regression from going back. We are still running validation before committing this as a fix to one of the future hotfix for 5.8. We will also evaluate if there are better options for future major releases.

Thanks,

Martin

Hi,

We committed a fix to the problem in the Release 5.8 stream (CL56702058\GH Commit). This will be part of the upcoming 5.8.2 release. It is similar to reverting to the old code but also addresses the problem that lead to CL50669491.

CL50669491 addresses a problem with Mover. You don’t need to get the new fix if you are not using it.

Regards,

Martin