Most areas in my game are separated by hard transitions- you can’t get from Area A to Area B unless you find a door and interact with it, at which point you get a quick loading screen and transition to Area B. However, since some areas are large enough that I still need level streaming to cut them up into manageable chunks, I can’t just use Open Level, I need a solution that keeps me within the persistent level.
Right now, I do this by giving each door a LevelName (corresponding to a sublevel) and a scene component that I manually position in the sublevel. When the player activates the door, it loads the new level, then teleports them to the scene component (at which point their camera is inside that sublevel’s streaming volume, and streaming takes over to ensure the level stays loaded):
It’s a little hacky, in particular there’s a chance that the level will load, unload before Teleport finishes, and let the player fall through the world, but Stop Movement Immediately seems to keep this from happening.
Where I’m unhappy with it is that I don’t like manually positioning every door’s target: I would prefer if the door itself could just call something like MovePlayer(destinationSublevel, destinationSpawnPoint) in the sublevel, and let the level itself curate its own spawn points like this:
That “feels” like a cleaner solution, the problem is actually getting a reference to the desired sublevel. Each level has a unique instance of a Zone_BP blueprint whose job is to inform the game logic that its area has been loaded/unloaded, and that blueprint seems like the natural place to put spawn/despawn logic, but I’m having a lot of problems figuring out how to get a reference to it. My best solution to date is doing something like this when the door is activated:
The problem there is that a sublevel will only remain loaded for a split second if I don’t teleport the player into it to activate the level streaming volume, and GetAllActorsOfClass is quite slow, so there’s a very real possibility that the desired level will load, then unload, before I’ve finished locating every Zone_BP and testing it against the one I want.
So is there an obvious way to improve my thinking here? It seems like sublevels not sticking around after I run Load Level is what’s muddying the rest of my logic, but I don’t think it’s possible to both use level streaming, and not have levels unload when the player isn’t within the bounds of their streaming volume.