I am trying to display a widget when the player begins the game. Most tutorials do this by creating the desired widget and adding that widget to viewport.
The problem I am having with this is that “begin play” gets called on every single replicated character and not just the player character.
So every character, not just the player character, ends up creating their own widget. They then post their widget on the view port.
This is very different from what happens on something like “event key press”, which gets called only on the player character.
How do I fix this so that only the widget of the player character gets created and posted.
I am also having trouble with the event dispatcher because event that runs is not called by the client that produced the event…
There are nodes like “SwitchHasAuthority” or “IsLocallyControlled” to determine if the PlayerCharacter instance is running on the Server, the Client or is only a copy of another Player.
Play a bit with them and you may find the solution (:
BeginPlay gets called on every single Instance of the Actor you use.
PlayerCharacter would be one per client on each client.
Confusingly, the client does not control either of the characters, which makes no sense to me…
The server on the other hand, controls one of the actor, which makes sense… the other should be controlled by the client (which it isn’t)
I can’t use this to say “if locally controlled, create widget and add to viewport” because that would only be correct for the server, not the client.
Authority though, unsurprisingly, is all held by the server.
happen to be boring at work, tired of checking Vive order status, and then this thread happens to be what I know.
To cut it really brief and short, a HUD widget are tied to a HUD class, and owned by PlayerController class, not the Pawn class.
A player controller is replicated so that when a input is made, it will be dispatched properly(then if you handle it properly that is).
So when a game begin, you just need to check the PlayerController, and if controller is local, you can then assign widget to the hud this controller owned.
Where your pawn can be pretty much just a default pawn that strip off any movement component or movement bindings.
Check the links in my signature, it would help you understand the framework and replication part a bit better.
maybe I cut it too short, yes, the controller will be thought as “local”, but there are only ever going to be one controller that can issue commands(which is the local controller).
(another exception would be local coop where you have multiple controller, but that’s outside of this discussion).
When I say you should do this on PlayerController class, it’s because HUD only exist on client side(even listening host, where you have all the clients’ replicated controllers, only 1 can get/set HUD.)
From your blueprint, you still run this on the Pawn class, it will never work this way as replicated pawn will always controlled by the controller locally(replicated or not).
I have this part figured out back when UMG is still experimental, so trust me, do all your stuff from the PlayerController class if you ever want your multiplayer to not drive you crazy.
EDIT: I look at your graph, for multiplayer game, you should avoid using getPlayerController function that need to specify controller index to work. Instead, you should just use getController when in Pawn class.
If you want to keep the code in the character/pawn instead of moving it to the controller, I found a solution that worked: Compare GetPlayerController and GetController by casting them both to PlayerController and comparing them for equality. If they are equal then you are working with the local player. Here is a sample setup: