Disable input for a specific player in a multiplayer game

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.

Do someone know how to disable the input for a specific players ?

Thanks in advance for all the people that are willing to help me :smile:

Create variable in game mode that is “active player”, replicate it (i think game mode is replicated anyway).

Then make macro in player controller that cuts off input (exec line) for any player that is not equal to active one.

This way you know that you replicate only that int variable, not some bigger chunk of data when you turn on/off input.

1 Like

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.

GameState is replicated not the GameMode.

1 Like

Thanks @Nawrot and @GarnerP57 for the solutions.

I will try to make both solutions :+1:

I didn’t think of the possibility to possess and unpossess the character for the active and non-active player :smiley:

I’ll come back when I’m done to tell you which solution work the best for me, or the one that I manage to make :sweat_smile:

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 :melting_face:
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 :slight_smile:

For the most courageous :sweat_smile:, I put the project on a free drive, here the link :
https://drive.google.com/drive/folders/1jYG-ptXr3Jp7vBV_i6LRM82WWrNhnYnT?usp=sharing

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

1 Like

Thanks a lot @Chatouille, it work just fine :smile:

Thanks to your explaination, I understand a bit much how the data are working on multiplayer and the behavior of controller, game mode & game state

Here what I’ve done in the game state, it’s not perfect because I’ve got an access issue, but I wanted to test your solution as quick as I can

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 :+1:

I’ll remove this access error and it will be all good, thanks again for your help and also @Nawrot & @GarnerP57 :grin:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.