UI Not Updating in Multiplayer

Hello all, I’m new to making multiplayer games and am still trying to understand how to update the UI from replicated variables. I watched a decent amount of tutorials and have been struggling to figure out how to update UI in multiplayer. Can anyone help explain what I am doing wrong?

Here is my current setup:

  1. Player Controller Event Begin Play → Is Local Player Controller Branch Check → if “True”, Delay for 1 second → Get Player Controller → Create Widget Blueprint, Promote Output to WBP variable → Add to Viewport.
  2. UI Main Menu class has a “Play” button. On click, Get Player Controller 0 → Cast to Player Controller → calls a Custom Event called “Request Start Game” → Calls another Run On Server Event within the Player Controller (RPC Event) → Casts to Game Mode to Start Level
  3. Start Level event pulls level info → Plug in level information and send to the Game State → Rep Notify Round Timer event in Game State
  4. On Rep Notify → Countdown Round Timer by 1 then Update the UI text.

From my understanding, I want to have a round timer value stored in the server, then this value gets sent to all clients (hence the RPC call). When doing Print Strings, the value for my round timer is correct all the way to the point where I update the UI Text Variable, however, the output value after the UI Text Update is 0 (so Round Timer before = 30 seconds → Set Round Timer UI text → Output Value of Set Round Timer UI Text is 0 seconds). I feel like my understanding of how the server and client communicates is off somewhere. If anybody could provide any sort of guidance or feedback, any help would be appreciated. Here are screenshots for some of my work if its any help.

Player Controller Event Begin Play:

Player Controller RPC:

Main Menu On Click Event:

Game Mode’s Start Level Event:

On Rep Notify Round Timer Variable:

Timer Countdown:

Update Round Timer UI:

Hi sethnguyen,

First things first, widgets/menus are purely cosmetic they should really only be added on the client, as the server has no use for them.

  • If you are planning on using a dedicated server for your game, you can use SwitchHasAuthority to enforce the widget is only created on the client (remote) rather than on server (authority).

  • If you are using a listen server for your game then SwitchHasAuthority isn’t needed as your first client is acting as the server and will need to see the UI as well.

Your main problem is that OnRep_TimerCountdown is what fires TimerCountdown, and TimerCountdown is what decreases the value. The OnRep fires only on the client and only when the value is changed, so in its current state you might find that OnRep_TimerCountdown is never being fired as the value isn’t being changed in the server. What you need to actually do is fire TimerCountdown on the server, which will trigger OnRep_TimerCountdown on the client.

There are a few other issues with your setup that are as follows:

In your “Update Round Timer UI” screenshot you have a function named “UpdateRoundTimer” which sets the text to the new time. Your other screenshots don’t show where/if that function is fired. Can you confirm it’s definitely being fired?

This function is also marked as “Executes on Local Client” and it appears to be inside a widget. Because widgets are cosmetic, as I mentioned above, I would avoid using any networking nodes in here. Functions marked “Executes On Local Client” only gets fired from the server, so anything inside a widget should really assume it’s being fired from the client, and if it’s already on the client it won’t fire.

My suggested setup is as follows

  • Store the Time Left in the Game State (so far so good)

  • In the Game Mode, fire a function every second which fires TimerCountdown in the Game State. The Game Mode only lives on the server and this makes us sure that it’s only the server who handles the time reduction

  • OnRep_TimerCountdown should then fire in the Game State

  • In the OnRep, tell the player controller to fire the function on the widget that sets the text to the time value (because the player controller is where you created the widget)

This makes the server manage what the time is, and then the time is replicated to the clients, so remove any “Executes on Client” code because this shouldn’t be needed with the setup I proposed above.

I hope this was helpful for you,

Matt