I’m currently working on level transitions using seamless travel, and I’ve run into some issues with GAS.
The ASC (Ability System Component) for my players is on the PlayerState, and I’m having trouble keeping the GAS state across levels.
Right now, my workaround is:
When seamless travel is triggered, I notify the PlayerState.
The PlayerState takes a snapshot of the GAS (all GEs, attributes, and GAs).
During CopyProperties, I pass this snapshot over.
Once the PlayerState has a valid pawn, I restore/dump the snapshot into the new ASC.
This feels like a lot of manual work just to preserve the ASC state between levels.
Is there a cleaner or more “official” way to handle this with GAS and seamless travel? It really feels like I’m working around the system instead of using the intended flow.
From what I’ve learned, it’s not recommended to add the PlayerState manually to AGameModeBase::GetSeamlessTravelActorList. Unreal already handles PlayerState during seamless travel, but not by keeping the same instance, instead it creates a new one and calls CopyProperties to migrate data.
That’s also where things get messy with GAS: when CopyProperties is triggered, the Pawn tied to the ASC has already been destroyed. This uninitializes the ASC, so by the time the copy happens, some abilities are already gone.
That’s why in my current setup I don’t try to snapshot inside CopyProperties. Instead, I take the snapshot of the ASC (attributes, GEs, GAs) as soon as seamless travel is triggered, before the Pawn gets removed, and then restore it once the new Pawn is valid.