Best way to have a PlayerCharacter interact with Pickup Actor (multiplayer C++)?

Hi !

I’ve been busy for days, looking through documentation, watching courses, but in my head it still hasn’t clicked unfortunately.

A bit of stage setting:

In a Listen server multiplayer game, I’ld like to have the PlayerCharacter go up to a Pickup Actor and then the name of the Pickup item appears above it.
Other players don’t get to see this text when they’re not close to it.

In my head there are 2 options to do this:

  1. The PlayerCharacter has a SphereCollision in front of him.
    When this Sphere collides with a ‘pickup’ collision box, it’ll trigger an Overlap event.
    Then from here the pickup’s Visibility will be enabled.

  2. Let the pickup in the tick function search for overlapping actors of type ‘PlayerCharacter’.
    If one is found, put the Visibility to true, to show the text.

Which one of these would be best performance wise?

For me the tick function seems the least performant.
There will also be quite a few of pickup actors around the map.

I also have questions about the first option

In this option, the player has a sphere collision that’ll trigger an overlap event in case it hit’s a ‘pickup’ collision box. I’m trying to get this to work, but my mind is still scrambled about Ownership & Replication & RPC’s.

What needs to happen inside this OverlapEvent to only enable the visibility of the pickup name for the character that actually overlaps with the collision box? Since the game is running on a listen server, I need some way to only set the visibility of the Pickup to show it’s widget. So I don’t think a Replicated bShowText is what I need here.

The Pickup Actor’s are placed in the level from the content browser.
They don’t belong to a PlayerCharacter.
I’m setting the Overlaps in BeginPlay of the PlayerCharacter without a filter (no HasAuthority(), since the Host also is a player here).

My result now is that for the server it works, but when a client goes to a pickup actor, the text shows up for … the server player (Host), not the client, even if the server player is not there. I have a log inside the BeginOverlap function. This log is printed #players_connected_to_the_server times and I don’t know how. I’ld expect it’ll only trigger for the actual player that is overlapping, not for all players.

My current code in TriggerBeginOverlaps:

UE_LOG(LogTemp, Warning, TEXT("Begin Overlap!!!"));
bool ImplementsInterface = UKismetSystemLibrary::DoesImplementInterface(OtherActor, UInteractableActorInterface::StaticClass());

if (ImplementsInterface){
	APickup* pickup = Cast<APickup>(OtherActor);
	if(pickup){
		pickup->SetItemNameVisibility(true);
	}
}

What am I missing to make this possible?
My guess is something about the ownership, but I don’t have a clue on what I should filter…

And to end … another question

Currently my Pickup Actor has a WidgetComponent, where the Widget itself is a C++ Userwidget I created with a TextBlock containing the Pickup Name.

Would instead of using a widget, a Text Render be better?

Using a WidgetComponent I can make the Widget in 3D space, just like a Text Render.
What are the advantages / disadvantages of using the one over the other?


Big thanks to anyone that could help me!

-Nick