Hello everyone,
I’m working on a multiplayer turn-based game and I’m hitting my head against the wall to disable the input for all the players, except for the player 1 (for example).
What I’m doing here is to disable the input for all players, then choose to select one and enable the input only for him.
For that, I’m looping through the pawn and the player controller, if the index is equal to the PlayerIndex, it’s setting two variables
Then, I’m using these two variables in the enable input. I’m using this function in a game state switch (the custom event is
Problem, when the index change, none players can’t move.
From what I understand, all the players share the same controller and when I change the index, the branch will always be False.
Unpossessing the pawn might be the most effective way if you want to do it from the server otherwise you need to politely ask each client to disable their own input using a replicated variable.
I think there’s someting that I don’t get that could make it work.
When I launch play, I can see in the controller blueprint 4 elements (1 spawned and 3 clients), for the Game mode, only 1. So I presume that each player has it’s own controller and I should be able to enable or at least print a message only on one player.
But nothing is working, I try to get different ID and player controller name, print it directly from the controller, using add custom event with different server mode and even go thorugh custom event in the Game Mode.
I think the problem is not so hard and I’m just missing someting pretty basic, but I don’t know what
Also, I try to uncheck “Run under one process”, it allow to print a message only on the select client, but it didn’t help me much.
If you have any ideas, I’m open to any suggestions
No, all players have their own controller.
On server machine, there is one controller for each player.
On client machines, only their own local controller exists. But it’s not a shared one.
Replicating controller index from a controller array which, I assume, is filled by GetAllActorsOfClass, is the worst of ideas. First, GetAllActorsOfClass does not have consistent order. But more importantly, client does not know about other clients’ controller, so GetAllActorsOfClass(Controller) on client always only return one controller : his own.
Even replicating the controller (as in, a variable of type Controller or PlayerController) is a bad idea because it will end up NULL on all clients who don’t own that controller.
Gamemode is a server-only class, and cannot replicate stuff.
Use GameState. It’s a singleton, replicated to everyone, meant to represent the current state of the overall game. Add a variable of type PlayerState to represent which player should have input. Mark that variable replicated with RepNotify. This will automatically generate a function OnRep_Variable. That function is called automatically whenever the underlying variable is updated and replicated.
From there, check if the variable’s value is equal to the local player’s PlayerState. If true, enable input, else, disable input. Something like this
Then, in my controller, I pretty much replicated what you did in your screenshot and it work just fine !!
For testing purpose, I just enable the jump on the selected controller.
Oh, and to get my controller array, I get it from the node OnPostLogin from the Game Mode and I copy it in a variable of the game state, no more Get All actors of class