What is the best way to stop an individual actor from unloading spatially at runtime.
I have a very large open world design with a few hundred thousand actors in. I have these spatially loaded and that is working fine.
The trouble is at runtime sometimes actors that i’ve referenced will unload if i move too far away.
Any actor can be selected at any time so unchecking spatially loaded isn’t possible.
I store references to the actors in the ui but these will be removed whenever the actor is out of range.
how can I say at runtime “I want this actor to not be unloaded”
is this even possible
For Example:
I have 200 buildings in a zone I wish to Select one building and keep it from unloading, the rest of the zone may unload as it wishes.
Once this building has served it’s purposes i want to release it back to streaming spatially.
Basically i want to “Pause” the spatial loading of individual actors
I already have them all in data layers. Organised by type and area. You can’t move an actor into a different datalayer at runtime though? So it’s either I turn everything in the layer on or off or nothing.
The user may select any one of hundreds of thousands of actors and that actor then needs to be permanent no matter where the user is.
Data layers don’t solve this as I can’t move the actor to a “always on” layer at runtime
They haven’t removed it, this is an editor subsystem blueprint so is only available in an editor utility blueprint.
even so the data layer doesn’t control the spatial loading. you can turn the layer on but it will still be spatially culled so data layers are not the solution in this situation anyway.
Seems to me it should be a simple thing to be able to toggle on and off the spatial loading of the actor at runtime.
Setting AActor:SetIsSpatialyLoaded in C++ does not affect this at runtime either.
The flag is changed but is ignored by unreal at runtime, so it must be cached or stored somewhere else.
I wrote two functions, one to read and one to set this.
Has anyone had any success in applying this at runtime?
In fact surely this would be the only way for this to function correctly.
Example:
I have an actor that has a property changed on it like visibility (it is now invisible)
I move out of range of the spatial streaming
I move back into range of spatial streaming
The actor has now reset and the changes made to the actor are gone, the actor is now visible when it should be invisible.
the only way for the Actor to have changes that are not removed is to disable spatial loading on that actor. So in summary spatial loading is only useful for actors that will never undergo any change whatsoever.
When an object is selected I create a dummy actor next to it
I then dynamically add a “world partition streaming source” component to that actor with a very low shape threshold this then acts as a streaming source and forces the actor to stay streamed
I really dislike this method but it’s the only thing I’ve got to work so far.
Things i found
adding the component to the object you wish to keep does not work (makes sense since the actor is being culled)
Creating a custom object with the component already on it and then spawning that actor does not work for some reason
Spawning a dummy actor then Spawning the component does work for some reason.
if anyone in the future stumbles across this and finds a better solution please let me know. I will come back and update this thread if I find one myself
If i get what you wrote, you have references and they break when the actor unloads.
Changing to soft and testing is valid before use should at least prevent the error.
Yeah that is a solution to part of the problem but “selected” Actors need to be loaded at all times. they are visible at all times even through other actors and are part of data sets that can be switched on and off.
Basically anything that is selected by the user needs to be loaded in.
They’re not in separate levels, they’re in one level divided by world partition . I was thinking of destroying them then spawning them again when they’re selected but it feels like a bad solution to the issue.
The real solution is for the “is spatially loaded” checkbox to work at runtime. I’ve submitted a bug report but i have no idea if it really is a bug. the c++ function changes the flag but doesnt have any effect on the streaming
In UE4 i had them in different levels but i switched to world partition in ue5
Dont know enough about 5 to suggest anything other than going oldschool.
Deleting and re-creating is probably a perfect idea here.
Particulalry if you want to manage a list and a single tick group for all the actors:
I’m assuming this has something to do with keeping actors acting via AI at runtime or similar.
Shoving all the ones that have to move around the world in a specific BP as child actors is your best bet.
The master BP allows you to control with a single tick all of their actions by looping the child actors and sending out message calls.
And you can probably have it in a data layer that’s always present or local, so they don’t stop functioning…
This is probably a good solution really. I will take a look at it.
storing streaming sources as nodes in the world is really hacky and I don’t want to build around that
Basically the project is not a game but a Data analysis tool for cities. for example if I want to check every area on the ground where a certain object is visible I need every object in a certain radius to be always on so it can be included in the study.
before, I just loaded every map and I knew nothing would unload. In my UE5 branch I’ve switched to world partition to see if I get performance gains. Not having granular control over what I can or cant stop from culling is holding me back though.
I’ll give this a shot as spawning the actors again is no problem and as you say storing them as child actors isn’t a bad idea.
I’ve been holding off on ue5 as my project is mature, so I haven’t used it much.