In my game I have some enemies which walk through the map and sometimes attack player. But on the client, sometimes I see “phantoms” of the enemies that have the animation but do not have their equivalent on the server, and nothing controls them so that they do not move, do not attack, and cannot be damaged - all player parts (including weapon etc.) just overlap them with no effect. But they are shuffled with the actual enemies and visually are undistinguishable from them until you come close to them and gazingly look whether they move. The explicit destroying on client does not help. This occurs with multiple types of enemies, some of them leave only fantom weapon, some have full fantom copies etc. I think that is an old problem and there must be many times verified fix. If so, please give me link to the topic with it. If it is not so, what blueprint do I need to show?
Bump. The topic is actual.
Double bump.
You would need to show the logic behind spawning and destroying an enemy.
Both should only be done on the server.
If you are spawning or destroying enemies without the is authority check then you could have simultaneous spawns on both client and server.
This type of logic should only be controlled via the authoritative server.
Hello! The enemies do not spawn and destroy in the full sense, just show and hide. These functions are called only on the server. Those “phantoms” are seen from the game start, after killing some quantity of enemies of some type phantoms of that type seems to disappear (but not sure), but after restart appear again. Here is the hiding logic.
Bump. The topic is actual again.
Double bump.
You dont have to pass on the information about if the actor is hidden to the clients. This information replicates automatically when the actor is replicated.
Just change it on the server and it will propagate to the clients.
It would be best to have a server side actor responsible for showing / hiding the actors. It could also keep there reference in an array (a use of object pooling).
Upon enemy spawn it would register with the pooling manager and be added to its array.
The next time you need to spawn the enemy call the manager function responsible for getting an innactive eneny in its array. Activate it, reset it and put it at tge needed coordinates.
Hello again! I do not “pass on the information about if the actor is hidden to the clients”. Probably you thought so when you had seen the “ClientHideEnemyPanel” node, but it just hides the panel at the top of the screen that shows the level and the health of the enemy. And I am already having the “server side actor responsible for showing / hiding the actors”, this is a GameMode that calls “Show” function when “Now” becomes not less than the Enemy’s “SpawnTime”. But this does not solve the problem. Which info should I provide to get more specific answer?
So I’m guessing you are calling the hide function on the server, correct?
Is this connected to an apply any damage function (server side) that once the health hits zero it calls hide on the actor?
The only reason why you would have phantom enemies would be if you called a function on the server that is not set as “reliable”. That means the server could drop the command if the network is saturated, skipping the function.
Yes, correct, but, unlike the “Show” function, not from the GameMode but from the “Destroyed” function that is called from the overridden “ReceiveAnyDamage” function. I’m guessing the last mentioned function is called only on the server, correct? I do not have replicated function in the Enemy or FightingCharacter blueprints. Also no replicated function in the Player blueprint are related to showing/hiding enemies.
Notice that if you override the destroy function and call destroy actor it will still actually destroy the actor, it just calls the overridden function before getting rid of the actor.
No, the “Destroyed” function has no relation with the “DestroyActor”, it just indicates that the fighting character has zero health.
Ahh ok. Got it. And is the Destroyed function executed on server?
I have already mentioned that it is called from the overridden “ReceiveAnyDamage” function. Also some enemies call the “Destroyed” function for player in their “Damaged” functions which are called from the same “ReceiveAnyDamage” function and also from the “Apply” function of ability. The last one is called, in its queue, from the “ApplyAbility” function of the player, then from the “AbilityServer” function of the player controller, then from the replicated to server function “ServerAbility”. So if the overridden “ReceiveAnyDamage” function is called only on the server, then yes.
Does this occur for players that join the game at a later stage? Perhaps its a replication error. On rep notify functions will always update even if someone joins later in the game, replicated do not.
This occurs on the clients. Of course, the server creates the game and then clients join to it, on different stages.
Perhaps linking a bool isHidden / isDead with a onrep notify that calls the hidden in game function would update this for later stage players.
No, this didn’t help. Phantoms are seen at the game startup, before any show/hide functions are called.
Are all enemies visible at startup? From your last comment I would think that some are supposed to be hidden at the beginning of the game.
Are enemies placed by hand in the levels or are they spawned. Also does their ai controller take into account possession if spawned and placed in world?
Inside of ai controlled character: