Hi there! For a week now I have this interesting problem with which I cannot really wrap my head around it. I’m trying to replicate a few events from owning client to all clients. Unfortunately for some reason my general approach (run on server if owning client -> has authority -> multicast) isn’t working and not even the run on server get’s called even though the actor is replicated and always relevant.
To be more specific, I have a weapon placed in the scene that can be picked up so far so good but when I try to fire it, client is unable to call server events eg. spawn muzzle effect, run line trace, etc. Unlike server which can do everything as it should.
Any suggestion would be greatly appreciated, thanks in advance,
I need a little more information about your setup. Are you running the server as a listen server (Client 1 is effectively the server with “authority” and Clients 2+ are connecting to Client 1) or a dedicated server (Server is launched separately from the clients, Clients 1+ are all “remote”)?
I’m guessing your weapon is set to “replicated”, so all clients see that the weapon is picked up.
When you fire the weapon, you need to make an RPC call to basically say “I fired my weapon / I pressed the left mouse button!”. So you’d need to call an event that executes on the server. Note that you should keep in mind what elements live on the client and what elements exist on the server (or both). I like referring to this document (http://cedric-neukirchen.net/Downloads/Compendium/UE4_Network_Compendium_by_Cedric_eXi_Neukirchen.pdf) on page 8, there’s a good chart to show what lives where. So, for example, if you tried to run an event on the server within a UMG widget, it wouldn’t work at all because the server code does not execute for UMG widgets.
Lets say you are running the code on your character. You have a Left Click event and you have it call another event, “S_WeaponFire” or whatever. S_WeaponFire needs to be set to “Run On server”. Now the server knows the weapon is firing. If you want, here you can perform checks to ensure the player has enough ammo or that the weapon is valid, etc. If everything checks out OK, call another event, “MC_WeaponFire” or whatever. MC_WeaponFire is basically just a way to broadcast that the weapon fired to all other players. Set it to Multicast and reliable. Here, you would perform your visual effects like muzzle flash.
Now you have the basic framework for setting this up. Ideally, you want to perform all your calculations on the server, so within the “S_WeaponFire”. If you want to perform a line trace and determine what actors are hit, do it on the server. Effectively, you don’t want the clients deciding if they were hit or if they hit another player - the server should make that call.
Yeah sorry forgot to mention that I don’t plan to use dedicated server in any way so it’s client 1 with authority.
Also I do understand the way how replication should work I’ve managed to make work multiple of them before it’s just this one I cannot figure out. So call stack would look like:
By pressing fire key blueprint interface sends command to the weapon to fire, fire event executes camera shake etc. and at the end calls custom event which should be run on the server (this is where the problem is, it never get’s fired) and from that the line trace and effects such as muzzle flash etc should multicast to all clients.
But don’t look for anything complicated in my example take it just like an actor that should do something on server and after that on every client.
Are you sure you understand replication? Clients don’t have authority over anything but themselves, they don’t have authority over the servers copy or any other copy. There’s a lot of dicey information out there (especially on Youtube) that teaches incorrect techniques. Start with this tutorial series by Epic here.
The server will always be able to do everything as it should when it’s a listen server, in this scenario it has authority over all replicated instances of its character and thus encounters no issues and doesn’t require any RPC’s to get things to work, the trick is to get things to work on clients.
I’ve attached a blueprint that works on listen and dedicated servers for you to study. Hope it helps. It fires a line trace from a “Gun Barrel” (reference your picked up weapon in place of this)
Also make sure your collisions are set to block whichever sort of line trace you decide to run so you get a hit result. In the below example you need to set the Capsule Component to block visibility. Visibility isn’t the best trace to use by any means for a gun but it works for the sake of this example.
Not the below example runs in a Character Blueprint.
That weapon if placed in the world is owned by nothing. When it is picked up the server has to SetOwner to something that the client already owns so the client becomes owner of the weapon.
Ownership is inherited so could be like this “PlayerController<-Character<-Weapon”. This means that if you SetOwner on the Weapon to be the Character that the client owns the client now eventually owns that weapon too.
Note that if a Client try to SetOwner nothing happens. It is ONLY the server that can change Ownership.
Be careful not to confuse Authority with Ownership.
Authority is given to whoever spawned the Actor and is never changed. If a client spawns an Actor it will never be able to use any network abilities like sending RPC’s or replicating variables.
Ownership can be changed by the server at any time.
First and foremost thank you all for finding time to reply, unfortunately I’ve probably gave too much unimportant informations. I really need to figure out just why custom event with marked run on server is unable to be called by any other client than listen server. That’s all. I don’t have problem with line trace handling or ownership (I’m not even changing it anywhere).
I’m now posting here only the relevant part, here is a few events that gets called locally after clicking left mouse button.
Here is where it gets wrong. HandleFireServer is called only from listen server. Client 1 and any other is unable to call it so every other event after that isn’t called and print string “handleFireServer” isn’t printed.
I have been working on a game and accidentally struck a stray key. Now, I cannot move my third person character with the usual key commands unless I hit the “Possess” button. After I quit I get an error message. “Blueprint Runtime Error:Accessed None trying to read property Animinstance from function:‘ExecuteUbergraph_ThirdPersonCharacter’ from node: (Symbol here like a tilted Q)Branceh in graph: (symbol again)EventGraph in object” (symbol) ThirdPersonCharacter with description: Accessed None trying to read property Animinstance. Does anybody know what this means and how I can get the game back to normal?
Doing exactly the same method you’ve done above everything works as expected with the printscreen nodes. Have you double checked that the blueprint is replicated?
Either that or the reference isn’t valid (or not replicated).
In the below example (on a dedicated server PIE, (but will work fine for listen server too), after having picked up a “Weapon” from the ground and attaching it the “PullTrigger” event is called from the Character’s BP and run on the “Weapon” BP. If i understand correctly, this is what you’re trying to achieve?
The only failure scenario’s I could quickly find is turning off replication on either the weapon, the character, or both. OR no having a valid Weapon BP reference (replicate your reference variable too).
(Sorryabt the green on green, was just a template map frm mrktplce)
Exactly, I have just a little more clutter in BP but still, it’s pretty much the same and that’s what bothers me. Normally my/this setup should work but this is some weird kind of exception. As I’ve wrote the actor is replicated and always relevant to prevent any issue such as this. Otherwise not even listen server would work which currently does. Also yeah sorry about that that’s just my bad grammar, I should have put there ; or something, to separate the line trace and the rest to prevent this confusion. Never the less thanks. I will probably redone this network communication in my weapons system there is obviously some weird problem maybe with clean actor I’ll get lucky.
Ownership is what makes “RunOnServer” possible so if the client that calls “RunOnServer” is not the owner of the actor when calling the event the server will drop the event and do nothing (there should be a warning in the log showing that the event was dropped).
So make sure that when the client picks up the weapon that the server “SetOwner” on the weapon to the pawn that the client currently possesses.
Oh ok this is new for me, and you were right. Since the weapon is placed in scene there is no owner being set on it. And of course output log shown it but I was so accustomed to string printing in the viewport that I’ve absolutely forgot about log tab existence. What a moron I am But this also raises a new question if I may, if I have let’s say, a lot of actors that have some network relevance like doors, deposit boxes (opening animation from timelines), etc. what owner should I set it on?
And of course thank you all very much for finding time to help me.
A lot of things don’t need an owner at all you just have to accept the limitation that you will not be able to use “RunOnServer” RPC’s on these actors.
If you have a treasure chest placed in the world the chest would not be owned by anyone, but how would a client then interact with the chest?
You would use something that the client already owns like the Pawn/Character and on this make a “RunOnServer” interact event. then the server-side character sends a regular event (non-RPC) to the chest and the chest can set a replicated variable and/or make a Multicast event back to all clients.
Sorry, I had assumed when you’d “picked up” the weapon that you’d done so using an RPC to attach the weapon to your character on the server (this automatically transfers ownership to you, thus enabling the functionality Garner has excellently described).
With something like a door you don’t need to own it to manipulate it, what Garner has been explaining is that you need ownership to invoke a Run On Server event, as without ownership (of the class you’re calling an RPC from) the event will fail to get to the server in every case.
So to clarify, ownership is only required to get you onto the server. Once you’re on the server you can manipulate things as the server in most any way you wish and replicate the changes the server makes to clients through one of either: Replicated variables, Run On Owning Client Events (RPC), Multicast (RPC) and/or RepNotify Variables (these are the ones that are important when you’re consider Net Relevancy, more detail at the end of this post).
All you need is a reference to the door/box etc. and the ability to get your input event (open box/door) from your client to the server. Since likely you’ll be using your player character class to do this action/input you need to get it to the server using your normal method. Since you already own your character by default the RPC event to “open door/box” will go to the server as expected without issue.
To ensure you always get the result you want, call your Run On Server event in the class that you own, you can cast/interface to call events on other actors/classes from there with confidence as you definitively have Authority over that thing as the server if you follow this procedure.
So when you’re on the server in your Character Class, you can use your reference variable to cast (or use an interface) to start your timeline that will run in the door/box class. (You can think of it kind of like the server owning the door, and you’re asking the server to open the door for you, and since the server has authority over the door, it will oblige. But for accuracy’s sake, the server, under the technical UE4 Definition, is not able to have “Ownership” of something, it’s more that the server maintains control over anything and everything even when an object is unowned. If you queried “Get Owner” on an object that had no owner, it would return null.
With regard to relevancy, this isn’t related to ownership. Relevancy will determine what a player who wasn’t within the net relevant range at the time of the event will see. In this case, if the client is too far away to be net relevant when you opened the door with an event, even if it was multicast (these are fire and forget events in so far as they will only change variables for clients who are net relevant at the time a multicast event is fired), the changes won’t be reflected for that client when he becomes relevant without a RepNotify that sets the new state of the door for it, and thus now is out of sync. (i.e. the player who became net relevant will still see the door as closed, while the server and any player that was net relevant at the time would see it as open).
Net Relevancy quite a broad subject and too detailed to start writing it all out.
I suggest you go and watch this excellent Epic Tutorial carefully, as it explains everything you need to know in regards to Net Relevancy.