Download

Hows does this work with online games?

I just don’t get how online works. I’ve followed the videos Epic posted about it, but there are some things that still remain unanswered for me.
For example, I have this UMG widget and I want that on construct, it resizes some variables based on each character’s HP (as each character
has a widget of its own), however, I’m not sure how I’m supposed to get a reference to each character.
Obviously Get Player Character 0 will only work with whoever is the server and it will fail with the rest of characters, but I also tried giving it
a different index (2, 3, 4, 5, 6 …) and still the client wouldn’t get its information right.
How am I supposed to achieve this?

In the widget bp you can use “Get Owning Player Pawn”, if that’s what you mean.

The problem is that that only gets me a reference to the controller. I want to access the pawn that the controller is using, and if I do “Get Owner Player->Cast to MyController->Get Owner Pawn->Cast to MyCharacter”, it fails on the Client but works in the server.

“Get Owner Player” will get you the reference to the controller, “Get Owner Player Pawn” will get you a reference to the character.

Can you explain what are you trying to do exactly? if you are using it correctly then the casting shouldn’t fail.

I’m suspecting that you are trying to make health bars, so you can see each client’s health from the server… (if so then you can’t do it this way).

What I was trying to do is to initialize some health bars on construct, but I guess I just can’t do it that way. I’m confused as to how all of this works in blueprint and code. Is there any place where this is explained in detail or something? Because I’m really lost. I can’t get anything working properly. How do I identify who gets damage and tell that to the widgets?

All the damage handling and health stuff should be done in the character blueprint (you can have a float variable “Health” for example).

Then in the widget, you simply use the “Get Owner Player Pawn”, cast it to your character class, get the float variable for health and then update the UMG health bar.

Which part are you having trouble with?

I’m still not sure what you want to do though… are the health bars viewable by all characters? for example Player1 can see it’s own health AND Player2’s health?

I’m just trying to create a widget (the HUD) so every player can see his own stats. I don’t need to see the other players’ stats.
Now, if I try to do what you said:

&stc=1

&stc=1

and this is what I do in the Widget

&stc=1

^Doing that fails casting on the client. Thus, health is not shown (as I left the health text empty by default).

Okay, that’s weird… what you are doing seems correct.

I will test this later if you are still having trouble with this but here is what I’m thinking… there might be a bug with the construct event (the order it fires could be before the character bp)… try adding a delay or run it at tick and let me know if you are getting the same.

Incredibly enough…

&stc=1

Seems to be working with a 0.1 delay. I guess it is indeed a bug.

Now I have another problem. I’m trying to handle some damage (not with the damage event, but manually just to test) with a simple Multi-Box trace. The problem is that the HP is being substracted from myself and not from the other player I’m overlapping with the trace.
Here an example of what happens after a trace:

&stc=1

and here’s the nodes I’m using:

&stc=1

I think the comments in the image explain it better. Is there something wrong with what I’m doing?

How is the trace being fired?

Have you tried to set the trace to ignore self?

I have, ignore self is enabled. I’m pretty sure I’m not hitting myself. Also, the trace is fired on “E” key press. I don’t think it should matter much.

EDIT: I also have this weird problem:

&stc=1

&stc=1

When the server mesh is being shadowed, the client mesh also gets shadowed. It’s really weird. Why would it transfer the state of the server to the client?

Wow… things are getting more weird by the minute :stuck_out_tongue: I have no idea how the shadow thing is even possible… could it be a(nother) rare bug?

About the trace thing… could you post some screens of the whole setup so I can try and replicate the problem?

Might be. I’m on 4.6.1 in this project. I might try to update to 4.7.6 to see if it solves the problem.

Also, here’s my whole setup:

&stc=1

And thanks for all the help. I’m really grateful!

Sorry I haven’t checked your setup yet (I’m lazy today :p) but a couple of things to note…

First of all, you should do the trace and damage handling on the server only.

Second, try to add “Self” in the Actors to Ignore array of the trace and see if that makes any difference.

How am I supposed to run that only on the server? It’s a key press. What would happen when a client presses that button?

I added some TextRenderComponents to the actor and I update the text displaying the current/max health, and there it does display the health properly and it shows that it is indeed decreasing the amount of health of the hit actor. However, it only works on the server, in the cleint it decreases the server’s HP, but the server isn’t notified about the change.

EDIT: Okay, I made it into a custom even and set to replicate Run on Server and now it works properly, but I have an issue. It seems that it is spawning 2 HUDs one on top of another on each window, thus, showing weird results. That’s also why when I try to update it doesn’t show values properly. Is there any way so I can add to viewport one instance of my HUD for each client/player?

I agree with you, that the key concepts of networking are quite confusing. Thats partially an issue of the docs, but also a bit difficult to understand due to the nature of networking in an 3d engine.
While it looks like client and server are in “the same world”, they are actually not. each one has it’s own game, but some parts of it are synchronized. To control the direction of synchronization (who is telling whom what to do), there is always only one single owner of any actor. everybody else also instantiates this actor, but he has no permission to change it (because its “remote controlled”).
This is actually important, or the game state can easily drift apart, eg if you have lag - or even worse, it’s a big security hole which would basically enable everyone to insta kill everyone else without even knowing where he is.

see this page for an explanation of ownership.

Only the following actors are actually owned by the client:

  • The client's PlayerController itself,
    
  • A Pawn that the client's PlayerController possesses, or
    
  • The client's PlayerState.
    

What now is really irritating is, that the pawn is spawned by the server and that the server can still change data on your pawn, regardless of who he has given the “possess” to (I think THIS is the thing that confuses the hell out of everyone).

This means, that you cannot damage the servers pawn (or any other players pawn), because you do not have permission to fumble with it!

When a player shoots in an FPS shooter, he may not do the shooting and damaging himself. All he does is send the “I pulled the trigger” to the server and then the server has to handle the projectile tracing and applying damage and notify you and all clients about you shooting around.

so much text but I forgot to answer the real question.
You trigger a RPC call to the server upon key press. See the networking tutorial videos on how you do it (it’s really simple).
The server may push data back to you with an other RPC call

It shouldn’t spawn 2 HUDs.

Could you show your HUD setup? I’m assuming you are adding UMG widgets… depending on how you connect to the server you might need to delete any existing widgets first (at begin play).

For some reason it stopped displaying 2 HUDs…
However, this was my whole setup:

&stc=1

This is what Update Percent and Display (Inside HUDWidget) does:

&stc=1

I’m assuming that this would create a HUDWidget instance for each Player spawned. Thus, by getting that Player, I could mod its widget separately.
Then here’s what happens:

Before doing anything:

&stc=1

&stc=1

After pressing E ON THE CLIENT

&stc=1

&stc=1

After pressing E ON THE SERVER

&stc=1

&stc=1

I know the way networking works in a 3D engine is meant to be hard, but it shouldn’t be this hard to get simple things working in my opinion.

Thanks for all that explanation. I knew most of it, but there were some details I didn’t know about.
The problem for me isn’t understanding how it works, but actually how to achieve it.

P.D.: Sorry for the extremely lengthy post.

Did a cursory look; here’s my checklist:

  1. In 4.7 there’s a order of operations bug with how/when clients are constructed on the server. Long story short, add a Delay(0) node to the front before you construct the widgets in the player controller Begin Play. Need to wait a frame for the player controller to be fully initialized.
  2. Make sure you’re only creating UIs for local player controllers. In a multiplayer game, there are proxy player controllers constructed on other machines, so you need to check if the player is local before you construct their UI. I think it’s IsLocalController.
  3. Pass self into the Create Widget call for the Owning Player parameter, on each player controller that constructs a widget.
  4. Sometimes playercontrollers need to be torn down and restored. Make sure on destroy of a player controller you remove their UI from your viewport.
  5. Cache a variable for the UI you created as a member variable, and make sure to check if it has already been set before you create the UI (after the delay), you’ll need this anyway to remove it on destroy of the PC. I’ve seen a bug before where a player controller’s begin play was called more than once. Bug may still exist in your version.