On our game, we have a persistent main level using world partition, and it sometimes loads a sublevel at runtime. That level is placed somewhere else in this main world and we teleport to it. Both levels need their own lighting setup, tha main one using a ABaseDaySequenceActor instance. The sublevel will use something else.
We use Data Layers to control which actor is active depending on which sublevel is loaded. This requires assigning Data Layers to our ABaseDaySequenceActor subclass instances in the editor, and also requires to setup the IsSpatiallyLoaded bool.
As we realized that ABaseDaySequenceActor (as a AInfo and in itself) does not allow to setup data layers, we figured out a way to enable those sections in a Base class of our own, using `ShowCategories = (DataLayers, WorldPartition, Rendering)`:
FDaySequenceActorDetails hides DataLayers/WorldPartition/Rendering via DetailLayout.HideCategory, overriding any subclass ShowCategories. We removed those calls
ADaySequenceActor::CanChangeIsSpatiallyLoadedFlag() returns false. Fixed by overriding to true in our subclass.
AInfo::ActorTypeSupportsDataLayer() returns false. Fixed by overriding to true in our subclass.
I now have some questions:
Does this sound ok? Why is the original DaySequenceActor not allowed to be world partitionned? Is there something we should be worried about by doing this? This actor contains cloud volumes, lights etc… So it makes sense, at least in our case, but I am wondering if I’m missing something?
Is there any other recommended pattern for making an AInfo-derived actor participate in Data Layers?
Is there any other solution that modifying FDaySequenceActorDetails in the engine plugin?
the other solution I would have would be to manually disable it by hiding it. Do you advice any other way ?
There isn’t any reason DaySequenceActors can’t support World Partition. DSAs can be dynamically spawned and work just fine. In fact, the main use case that we had in Fortnite is that DSAs are always dynamically spawned. That said, the primary reason we dynamically spawn in the DSA is so that users don’t ever have to manually place a DSA in a map. This helps with LDs working on sublevels and still wanting to preview lighting without potentially accidentally injecting an extra DSA into the persistent level. For those reasons, we based the DSA on the AInfo class.
The changes you’ve proposed make sense to me. If anything, I think we were a bit overzealous in hiding the WorldPartition, Rendering and DataLayers categories in our details customization. That is something we can fix on our end so that you don’t have to touch engine code to make this work.
I do want to add some more color to how we handle different lighting setups in FN though as this might be relevant to you. To achieve different lighting looks in FN, we make heavy use of DaySequenceModifierVolumes. These provide us a way to inject a new set of sequences into a DSA’s root sequence without needing to spawn & swap to a new DSA. These volumes fully support blended transitions and also fixed time setups. Crucially, pausing a DSA stops it from evaluating which means it is no longer responsive to conditions and gameplay, so having a dedicated fixed time setup while still running can be useful. You might find this video relevant where Paul Oakley discusses how different POI lighting setups are achieved using DaySequence in FNBR:
If you have wildly different component setups for your DSAs, you can still use DSMVs by having sequences show/hide particular components with visibility tracks.
With that all said, I don’t think you’d have any particular issues with your approach. It is a less travelled path, but we have had setups where we toggled between DSAs in the past. It was not necessarily through World Partition, but showing/hiding worked well in those cases. You just have to bear in mind that hiding a DSA does not stop it from evaluating.
Anyway hope this helps. Happy to answer any further questions you might have. In the meantime, I will fix up FDaySequenceActorDetails to no longer hide Rendering, World Partition and Data Layers categories.