Client HUD not updating, I'm dying.

Hi guys,
first of all: sorry for the title, but this problem keeps me from doing some progress for about a week now. :mad:
Essentially what is happening:

ListenServer: I pick up an Item, add it to the Inventory. The player sees the Item instantly in his Inventory Widget.
Client: I pick up an Item. Item gets added to the Inventory. The player does NOT see the Item in his Inventory Widget. Client picks up another Item. I now see one Item in the Client’s Inventory Widget. Pick up more Items, and Client’s UI is always one Item behind of his actual Inventory.

In both cases, the Inventory variable is correctly replicated. I test this by outputting the number of Inventory Items on Client and Server, it’s the same.
First I thought that I update my HUD on the Client too early, that is before replication has taken place. Moving the HUD-Update to an OnRep_Function didn’t fix the problem though.
All HUD-Updates are Clientside Functions. Adding to the Inventory is done on the Server. I also checked all my pointers.

The Inventory and InventoryManager are UActorComponents in the PlayerController. Everything is set to replicate via SetIsReplicated(true); after creation. Every important Variable in these UActorComponents is set to replicate.
After further investigation, it seems that when I want to create the InventorySlot for the Item that I just picked up, the size of the Inventory is not updated.

Now here’s a list of what I do when picking up an Item:

  • 1. Server: Call InterfaceFunction “Use” of that Item from the PlayerController (takes a Controller Reference (self) as parameter)
  • 2. Server: Cast PC Reference to my custom PC, get his InventoryManagerComponent->AddItemToInventory(ItemData, PC->InventoryComponent);
  • 3. Server: Add Item to Inventory. Call OnRep_Function() which calls the two following Functions:
  • 4. Client: Clear all Inventory Slots in InventoryUI
  • 5. Client: Get PlayerInventory in InventoryManagerComponent (which now holds updated replicated Value), and add an InventorySlot for every Item in there.

I think the problem lies in step 5. When I pick up the first Item and output the Number of InventoryItems in Step 5, it says the number is 0. What’s happening here?

Even if I don’t do it via an OnRep_Function(), it still doesn’t work. It’s so weird.
I feel like I’m missing something basic. As I said, every Function is set to Client or Server respectively and no pointers are NULL.

Has anyone here encountered a similar problem? I really feel like the solution “should” be easy since it’s such a weird problem and I couldn’t find much on the net about it.
Please save me from this suffering, and thanks for your time

PS: If you guys want to see some code directly, I can post it! Essentially, I bought an Action RPG Inventory (can only recommend!) and I’m trying to translate it to C++. I didn’t do much yet, just adding to Inventory and showing the Item there.

I also posted something similar in the ARPG Inventory Thread. There’s at least some code and Screenshots there if you need more info. I can always post some more code though!

**Edit: ** When I update HUD manually (on button press) after adding an Item to inventory, it works. Some weird delay/connection stuff must be going on?! Updating HUD via button press is not viable for me. I’m really confused now.

**Edit 2: ** I’d also settle for a working example of this in C++ :rolleyes:

**Edit 3: ** It “kinda works” when I create an OnRep_Function in the InventoryActorComponent for the Inventory Property itself. In said OnRep_Function I get a saved reference to the Owning PlayerController and call InventoryComponentManager->“UpdateHUD()”. There’s some noticeable delay when updating the HUD though, like probably half a second or more.

Two things I would check:

  1. In your UpdateHUD function, are you accounting for the first index of your inventory array being “0”?

  2. There could be an issue with using OnRep for the array property, rather the component. I picture a problem with the client receiving the OnRep to update the hud, but the component itself has not replicated yet with the current array. It would update using the previous version of the array. “One step behind.”

Hi, thanks for your reply!

  1. Yes I do, and it works perfectly for the ListenServer! :slight_smile:

  2. I didn’t use OnRep on the InventoryArray itself, but on the InventoryActorComponent Reference in my InventoryManagerComponent. (Both UActorComponents of my PC)
    Whenever I want to change something in the Inventory, I change the InventoryActorComponent Reference in my InventoryManagerComponent, which is Replicated.

Now as I said in my last edit, it seems to “work” when I OnRep the Inventory Array in my InventoryActorComponent directly, and call an UpdateHUD function from there. But this is not like in the Blueprint example and feels very unorganized.
Sorry, this is probably very confusing to someone not having the code. :frowning:
I hoped this was something several people encountered, something like a “common” problem, but I guess it’s my own bad design.
Again, thanks for your time!

What do you mean with ListenServer exactly, do you mean the function node is set to Run on Server - reliable?

Basically when the player does not sees the item the function Client set inventory slot item is not proper, do some print string tests to follow the chain of functions and variable values once the inventory is opened, for debugging.

The first 12 or 13 numbers of the player inventory are the equipment slots, thus the first item number which should have a valid InventoryItem value is 13 or 14, unless you are checking for equipped equipment.

I think I narrowed it down to my Inventory being replicated very slowly. As I said, I got the OnRep_Function to work and I update the HUD in there. This can take up to second, I guess I have some networking problem unrelated to the Inventory, since the same thing happens when I change my Health Variable. When I check the ping in PIE, it’s around 14ms so I guess it’s not that. Very weird.

**Update: **
Okay I think I got it, I’m such a dummy…
“MinNetUpdateFrequency” was set to “2”, which means when replication of a variable occurs unsteady, it’s throttling down the how often an actor is considered for replication (if I understood it correctly).
Two updates per second means I could experience a maximum delay of half a second, which is almost what I felt it was. :cool:

Now I just set it to 20, which is probably overkill, but it updates very smoothly.
If someone’s reading this, I’ve got a followup question: How do you determine a good Value for UpdateFrequency variables? Does anyone have some resources on that? Does Unreal provide tools to measure bandwidth usage?
Information very appreciated but not needed at this point in development. Sorry for making such a big fuss of this problem, you can’t imagine the relief I’m experiencing right now.