Supporting Group Actors inside Packed Level Actors

Our level designers are working with packed level actors and would like to be able to use group actors for grouping as an organizational tool inside them.

This mostly seems to work already except for a couple of issues.

  1. An issue with render state can cause some of the meshes to disappear in the level editor viewport.
  2. There are warnings about the group actor root component not getting packed (seeming benign, although I originally wondered if this was causing the other issue)

This has been observed in both unreal 5.6 and 5.4

The bigger issue is with the rendering breaking and so I wanted to explain how to reproduce that:

1. Start in Blank Level

2. Place two cube actors

3. Select both cubes, right click -> Level -> Create Packed Level Actor

4. Edit the new PLA level instance (Ctrl+E)

5. Select both cubes and group them

6. Exit the LI (Esc key), let it save as it prompts

Observed Result: The cubes inside the PLA disappear from the rendered level until you do something to cause them to re-render, eg. move the PLA

Expected result: The cubes should not disappear.

Some other observations:

Editing the PLA and deleting the group inside the level instance editor then exiting the editing of the level instance will also cause the issue.

Adding certain other actors like Trigger Volumes to the level instance and exiting will cause the issue.

If you add another cube to the level instance after making the group actor edits, it will not have the issue.

Furthermore, I wanted to share the changes I made to solve this issue for your consideration for upstreaming and for your feedback on whether this is warranted and wise on our end.

To solve the warnings from the packed level actor builder, in FPackedLevelActorRecursiveBuilder::GetPackClusters, I added an extra discard for AGroupActor, as follows:

if (LevelActor == Level->GetDefaultBrush() || 
    LevelActor == Level->GetWorldSettings() ||
    LevelActor->IsMainWorldOnly())
{
    InContext.DiscardActor(LevelActor);
}
// <PATCH> #SupportGroupActorsInPLAs
// AGroupActor is an editor only actor which we can ignore when packing to avoid spurious warnings.
else if (LevelActor->IsA<AGroupActor>())
{
    InContext.DiscardActor(LevelActor);
}
// </PATCH> #SupportGroupActorsInPLAs

To solve the rendering problem, I added the following code in APackedLevelActor::OnCommit(bool bChanged)

void APackedLevelActor::OnCommit(bool bChanged)
{
    Super::OnCommit(bChanged);
    // <PATCH> #SupportGroupActorsInPLAs
    // It seems that when certain actors are added or removed from a PLA, such as group actors or trigger volumes,
    // it can lead to the render-state being somehow lost when you exit the editing of the PLAs.
    // Adding this unconditional MarkComponentsRenderStateDirty fixes it.
    // The early return was added to fix an issue with reinstancing https://github.com/EpicGames/UnrealEngine/commit/63825d580640b834f483385fe10bc2997638f703
    // however by calling MarkComponentsRenderStateDirty before Builder->UpdateBlueprint we may be fine.
    MarkComponentsRenderStateDirty();
    // </PATCH>

Potentially the later call to MarkComponentsRenderStateDirty in the same function could be removed but i wanted very much to minimize changed code in our patch so i left that behaviour in for now.

In summary, please let us know if proper support for group actors can be added to Packed Level Actors, and please let us know if these fixes seem reasonable to do so.

Many thanks in advance.

Hello!

We reviewed the code you shared and your fix of marking the PLA as dirty is correct. I was committed with CL45325208.

We did not change the builder as the groupe actor was already being discarded in other part. The warning is normal in this case.

Regards,

Martin

Thank you very much! Is the warning not essentially a false alarm? I would love to minimize any false alarm and confustion if this is a valid thing to do with Group Actors.

The output is just logging and there is no mention of a warning. I’m also not sure how the proposed change is improving the log as the message should just be replace with something that looks like: Actor ‘XXX’ ignored (Actor Discard)