Problem with multiplayer damage when health is stored in player controller

Okay, I’m stuck on why it is doing this?

I wanting to have the health variable stored in the Player controller so that when players possess another character they retain the same health variable.

but when I am trying to damage a player it only damages the Host of the listen server, but when I have the variable stored locally it works as expected

(vid of health var stored in PC)

(Vid of health var stored Locally)

(Code that runs after any damage node is called)


Just to clarify I’m still learning networking and replication, just leaning as i build this game. So I’m unsure on why this is happening, cause the health variable, Player controller Ref & The player controller are all replicated

Help will be greatly appreciated

Hi @Gamingninja5115!

So we can get some more insight, would you mind sharing the portion of your blueprints that call the player damage event and/or handle replication?

In the meantime, here is some live training that directly addresses health in a network multiplayer environment as a possible solution or insight into your issue:

Network Multiplayer Fundamentals | Live from HQ | Inside Unreal

Any additional information you can provide will be a big help!

1 Like

Ok, Here is the damage logic

Input & event call
Fire Input

Line Trace logic & apply damage node

On any Damage node & event call

Going back through my code, i noticed on the event where im calling the client to update its health on player controller i was calling it on server as well, ive changed that to run on client

and i get some slightly different behaviour now.

(I’m Controlling Client 1, Bottom right)

It now does damage to a client but also still does damge to the Host. So doing damge to client 2 will do that same damage to host, but doing damge to host wont do damge to either Client. When Host already has damage done. When moving to damage Client 2, clients 2 will jump to same health value as Host once damaged.

I’ve also turned off the player controller replicates

on or off, this doesn’t seem to change behaviour

On a quick look at your BP:
The first custom event rep on owning client (CR Fire) wont really do a thing.

If you are inside the player controller, what player controller are you explicitely referencing then and where do you asign it? You dont need to reference a player controller inside the player controller BP except for referencing other pcs.

Let every logic happen inside a server rep event. Just replicate the health. No multicast or rep to client needed.

And controller replication on.

1 Like

sorry about the confusion, all blueprints shown are in a character class and I’m getting a reference to player controller on begin play

The only code I have running in the player controller is spawning the Widget BP

I’m just storing the health variable in the Player controller with a default value of 100. Then decrementing it in Character class through a reference

Use get “owning controller” instead of indexed pc.
At most times for multiplayer you can forget about indexed pc.

I would recommend getting all your logic about damage handling into the controller instead of just using the controller as storage for health.

On damage event get owning controller and call a custom event you create for handling the damage logic - inside the controller. So you have everything centralizied. (Logic handling inside controller with server replicated custom event)

1 Like

So i tried what u suggested, Moved my damage code over to PC & have a custom event that calls in character_BP on any damage. Same behaviour tho, i have an print string going on when health is decremented and it says same thing, that Host controller is being damaged.

also in Character class when I’m creating my reference to the Player controller the only node that works is an indexed “get player controller”. “Get Controller” just returns an error when a client try’s to damage

(In Player Controller)


(In Character class)

Let me get to my laptop.
In character class:
image

Straight out of my working research projekt. But if you cache the controller be ware that if you change the possesor of the pawn you have to handle that too.

On a Multiplayer solution the players get indexed so you are just referencing the player controller at index 0. That explains your behavior shown in the first video.

1 Like

oh and forget cr_dealdamage, thats just redundant due to the health already gets replicated and changed from the server with sr_dealdamage.

Also the node that im using to get the controller inside the pawn - did you use that when getting the error? If yes, which error?

1 Like

Yes i used the “Get Controller” node, it works fine when a client is damaging Host, but when client try’s to damage another client it returns the error “accessed none” on the reference to player controller, trigured on the event call after “Any Damage” node

also for the CR_DealDamage Event, how i understood it is that it was updating the clients local copy of the health variable and that SR_DealDamage was updating the server’s copy of that clients Health?

so where you meaning get rid of the event all together or just changing its replicate property?

When using the damage code I now have in player controller in the Character class with a local health variable the damage system works perfectly. but moving it to the Player controller and calling an event though a reference is where it breaks down.

Using “Get Controller” node returns an “Accessed none” error for clients & using “Get Player Controller” node only calls to damage the host?

Okay I think I actually got it working.

(I’m controlling Client 1, bottom right)

Now using an Interface in character class to call the decrement health event in Player Controller

(In Character Class)
AnyDamage2

(In Player Controller)

Thanks to @wefl & @Quetzalcodename for the help

Though I’m still confused on why using a PC reference would only call the host PC instead of the instanced PC?

Because any damage gets only called on server. And you casted on client before storing it into a non replicated variable (character class is owned by client iirc) at first. Just cast directly inside any damage with get controller, should fix it, or replicate the casted controller variable. I could be wrong though its 3am and i just woke up lol

yeah that worked a treat.

I changed it a bit, so I’m still casting on event begin play but I’m now running the cast to player controller on both server & owning client through events

(In Character class)

yeah thanks heaps @wefl

1 Like

Fancy setup, well I never tried it this way. I still suggest to replicate the variable though.

Glad I could help. Good luck for your further work.