I’m wondering how to stop the local client from responding to a server’s multicast. I’m just not sure what is the best way to do this.
I have a situation where a player can perform an action by pressing a key. The action results in some client-side visual effects and the server then does a few things itself, nothing to special. So here is what I’m doing at the moment.
- Client 1 presses the key.
- Client 1 starts playing visual effects (to hide latency).
- Client 1 calls a “Run on Server” event to notify the server of the action.
- The server validates the action and does a few other things.
- The server then calls a “Multicast” event to notify all clients of the action.
- Client 2 receives the “Multicast” event and starts playing the same visual effects on Client 1’s character.
7. Client 1 receives the “Multicast” event and starts playing the same visual effects AGAIN on its own character.
Step 7 is the problem. I don’t want client 1 (or whichever client triggered the event to begin with) to respond to the multicast event and start playing their visual effects again for a second time. Is there some way to stop the triggering client from responding to the multicast or some way for the client to check if they should ignore the multicast. I could probably get around it by setting a bool or something and checking it again later, but that just seems hacky. I have a feeling there is a better way that I’m not aware of as this surely must be a common problem.
As far as I am aware there is no way to exclude clients when using a multicast in blueprints. You could try sending the calling player controller when the event call is made. When it is received by all other clients, simple do a check (branch) and see if the Calling Player = self. If not then you can pass through the branch and spawn the visual effects.
Another alternative would be not use a multicast, but do your own check and looping through each of the players and then branching and see if the calling player. If it isn’t, then it can call the event.
Setting a variable on the Client that says its already applied the effects itself is perfectly fine.
Its better than attempting to replicate a variable across the network, network optimisation is important.
Maybe this is to some help , he is using != self , or as in the youtube link Is locally controlled ->NOT -> Branch
Don’t know if it works though.
The Problem with setting a variable is that it has to be resetted after a certain time, for instance I’m using the script to spawn bullets. If you’re firing the rifle on automatic mode the bullets are spawning so fast that, if the client has a high ping it does’nt work with setting a variable. The variable has to be resetted very fast to spawn the next bullet by the client. So after signal to spawn a bullet returns from the server the variable itself is already resetted and bullets are duplicated in the clients view.
Even though bullets are handled by the server I think it is better to spawn a bullet immediatly on the clients side, so that there is no delay after shooting.
I tried the != self way, but I couldn’t get it to work.
Maybe you have some Ideas to get this problem (which occurs very often in different situations) solved, so the client isn’t affected visually be the ping.
Just send initiator id in multicast.
I had the same issue with (gameplay irrelevant) visual effects that should just play as fast as possible and did a workaround via excluding my initiator afterwards. But I don’t like the fact that the server is still wasting bandwitdh via causing a confusing message that have to be sorted out by the client that caused it and executed the effect already. It would be way better if there would be a further repilcation method like “Multicast except initiator” so the server would not send it to the causing client that have to filter it out afterwards.
if(GetLocalRole() == ROLE_SimulatedProxy)
//do it for all remote clients
Is there a Blueprint equivalent to this?
Another idea, using Blueprints with the same function (StartDash) being called on the owner-client, replicated to run on the server, which then multicasts to all (but only executing on server + other clients / early-out on owner-client):
So basically just pass along that this is the multicast case being called (if the server does it) and if so, exclude the original client. As someone earlier noted, this comes with the disadvantage of unnecessary network traffic (packets to the owner-client which is going to ignore it), but I expect it to be fine if this happens occasionally.
In my case the non-owner clients can handle the entire Dashing/StopDash (timing/states - no movement logic) themselves, so no need for replicating a StopDash (which server would never time correctly, due to lag) and the animation system has all state/timing info it needs.
And yeah, an option "Multicast (except owner-client) would really be convenient.