Replication issue with Spawning Actors with Level-loaded Actors as Templates

Hi all,

I have been trying to update a plugin I have been making to replicate its actions across the network.
One of the actions is Duplicating an Actor.
I use the following to spawn an Actor using a Template (this is ran on the Server):

		FTransform spawnTransform;
		FActorSpawnParameters spawnParams;

		spawnParams.Template = templateActor;
		
		if (AActor* actor = world->SpawnActor(templateActor->GetClass()
			, &spawnTransform, spawnParams))
		{
			//other code 
		}

Inside the “if” function above, I add the newly created actor to a list and then it waits until BeginPlay has finished for all of these actors (once HasBegunPlay is true, I guess it’s safe to say they are replicated…?)

Anyways, this works like a charm if the template used is an actor that has been spawned in Runtime. All clients can see the newly spawned actor. This, unfortunately, does not work if the template actor is a Level-loaded Actor (i.e. actors that were added via the Editor).

The warning message that appears right after this issue occurs is as follows:

LogNet: Warning: UActorChannel::ProcessBunch: SerializeNewActor failed to find/spawn actor. Actor: None, Channel: 15

A video explaining the issue visually can be found [here][1].

Any ideas will be highly appreciated. One thing to note is that I tried running it in both UE 4.22 and UE4.24. Both have the same issues.

[1]:

1 Like

Just a heads up:
The first part of the video I duplicate a Runtime-spawned Actor (which works fine)

In the second part of the video, although a bit ambiguous, I am trying to duplicate a level-loaded actor but the LogNet message above is shown in the Output Log and nothing appears on the Client-side. Only the server manages to duplicate it correctly.

Update on the Issue

Finally found a way to solve this. (Posting if anyone interested in the issue).

The issue is, that when duplicating, all the properties are copied over, which makes sense, because it’s a duplication (duh).
This includes copying the actor’s bNetStartup state. And that is the problem. No further check is done.

If bNetStartup is true that means that the actor was loaded from the level and so the actor is no longer valid for replication gather. Therefore the spawn never occurs.
My solution to this was to add this following line before the SpawnActor function is called.

templateActor->bNetStartup = false;

This makes the newly created Actor behave like it should: a newly created actor and not a level-loaded one. After this line was added, replication started to work on these level-loaded replicated actors properly!

My personal opinion is that this is a bug up until Unreal 4.24 (haven’t checked 4.25… yet). It would be nice if this was fixed or if someone told me an explanation on why this is not a bug that needs fixing…

1 Like

I just ran into the same issue on 4.27.1. I spent a day or so digging into the engine code and trying to find a minimal reproducing example until I found this post. Thanks so much for coming back and posting the answer. Your workaround worked for me too.

If it’s not a bug, it’s at least very confusing behavior. It’s super non-obvious and I have no idea how you figured it out.

I feel like either bNetStartup should not be duplicated if the actor is set to replicate, or the LogNet warnings should be improved to reflect what’s going on to make it easier for people to pinpoint the issue.

1 Like

can you do this on blueprints?