Blueprint references to level Actors are lost when streaming out and back in the level
We noticed that Level Blueprint references to Actors on that level are invalid after streaming out and streaming back in that level. It happens only in multiplayer on both server and client.
After digging into the code I noticed that normally FLinkerLoad::Preload() is called for both Blueprint class object (object of a class "BlueprintGeneratedClass") and a Blueprint object itself (object of a class "SomeClass_S_C").
However when running in multiplayer, FLinkerLoad::Preload() is called only for a Blueprint object. So FLinkerLoad::Preload() is not called for a Blueprint class and FLinkerLoad::FinalizeBlueprint() is never called which in effect doesn't assign proper Actor* pointers to references in Blueprint.
Did anyone come across similar issue? It may be not related to multiplayer, at least not directly.
asked Sep 11 '18 at 08:54 PM in Blueprint Scripting
I'm sorry for the late reply here.
It's definitely not forbidden. Level Blueprints are actual blueprints, and are wrapped / managed by an ALevelScriptActor. If you take a look at the constructor, you'll notice that we do explicitly enable replication and set some other networking state.
Just so I fully understand the problem, you have some level A that references actors. When the level is Unloaded (unstreamed) and Reloaded (restreamed) those references are broke.
I have a few questions, mostly just for the sake of clarity:
In this case, are you talking about the BP of an actor, or the BP of the level that owns the references?
So, it sounds like in this case FLinkerLoad::Preload is not being called on the Blueprint Class for the Level Script?
When we unload a level we go through and mark all Actors and Subobjects owned by the level as Pending Kill and perform a garbage collection. This system is completely separate from Networking, and if any system has references to these objects they should be properly nulled out regardless of whether or not the references are strong or weak (Strong being a UPROPERTY and weak being something like TWeakObjectPtr).
Aside from that, the networking system generally keeps very few strong references. The few things it will keep a reference too are generally either other networking objects that shouldn't be level specific. The main exception to this is for UActorChannel where we'll keep a pointer to the Actor the channel is associated with. Again though, this should get cleared away by the Garbage Collection that happens as a part of unloading the level.
I'll work on seeing if I can reproduce the issue based on the description you gave. I'm not sure how many others have seen this issue.
Follow this question
Once you sign in you will be able to subscribe for any updates here