RedditPP Mascot

RedditPP

r/unrealengine • … • u/bitches_be

SetOwner call before calling ActorComponent RPCs: is this a good practice?

I'm working on an inventory ActorComponent that is replicated and using a Fast TArray to hold the inventories slots/items. Most inventory functions like swapping items can be called by server or clients and calls the Server RPC version of the function.

This works fine when this component is attached to my Characterss. The functions that call the Server RPCs are being called from the widgets the represent the inventory and it's contents.

The issue I ran into was when this component was attached to a replicated actor in the world. The server can make calls as expected and changes are shown for all players but clients get the error about "No owning connection for actor. Function will not be processed."

This tracks with what I have found online about the client's not owning the connection to the world actor's inventory component.

I'd like to avoid having to make functions for each inventory RPC function on my Character/Controller outside of the component to pass these RPC calls back through the controller.

What seems to have fixed this error was calling SetOwner() on the world actor - setting the character that opened the chest as the owner. The last player who opened the chest is set as the Owner.

I've only tested moving items around in the inventory of a world actor. The moving/swapping is replicated for all players now as expected. I haven't implemented much else yet but want to make sure I'm building out my system properly before I get too far in.

Is this a good way of doing things?

Does this mean whatever client was set as the Owner last can now make any call without verification/authority from the Server?

**Update:**

I was able to get this working properly without having to check or set any owner. As luthage pointed out, I was not routing my RPCs properly.

Now my inventory functions have inputs for the inventory components, sometimes two as my ExchangeItems() function uses. To route the RPCs I'm making calls on the Player owned inventory component to make changes on the target inventory component.

Posting what I have here for others:

UFUNCTION(BlueprintCallable, Category = "Slots") void ExchangeItems(int FromIndex, UInventoryComponent* FromInventoryComponent, int ToIndex, UInventoryComponent* ToInventoryComponent);

// [Server] Swap items between InventorySystemComponents. Merge item stacks if the first and second index have the same static and dynamic properties UFUNCTION(Server, WithValidation, Reliable, BlueprintAuthorityOnly, Category = "Slots") void ExchangeItems_Server(int FromIndex, UInventoryComponent* FromInventoryComponent, int ToIndex, UInventoryComponent* ToInventoryComponent);

void ExchangeItems_Internal(int FromIndex, UInventoryComponent* FromInventoryComponent, int ToIndex, UInventoryComponent* ToInventoryComponent);

And here is how I am making those calls from my Widget class:

UInventoryComponent* Inventory; // Inventory component reference variable that lives on the slot widget class UInventoryComponent* CharacterInventory = FoundInventories[0]; // Grabbing the first found UInventoryComponent on the widget's owning player pawn CharacterInventory->ExchangeItems(DragVisual->VisualInventorySlot, DragVisual->Inventory, SlotIndex, Inventory);

— 0