diff --git a/getting_started/first_3d_game/02.player_input.rst b/getting_started/first_3d_game/02.player_input.rst index 558f94d7068..3420e115af9 100644 --- a/getting_started/first_3d_game/02.player_input.rst +++ b/getting_started/first_3d_game/02.player_input.rst @@ -143,7 +143,11 @@ Leave the other values as default and press *OK* .. note:: - If you want controllers to have different input actions, you should use the Devices option in Additional Options. Device 0 corresponds to the first plugged gamepad, Device 1 corresponds to the second plugged gamepad, and so on. + If you're developing a local multiplayer game with multiple controllers, + the common approach is to leave the Device option set to All Devices. + The system automatically differentiates actions triggered by different + controllers using the InputEvent player property, + so **you don't have to duplicate actions for each player!** Do the same for the other input actions. For example, bind the right arrow, D, and the left joystick's positive axis to ``move_right``. After binding all keys, diff --git a/tutorials/inputs/controllers_gamepads_joysticks.rst b/tutorials/inputs/controllers_gamepads_joysticks.rst index b541aa60dbc..dff073a2e4a 100644 --- a/tutorials/inputs/controllers_gamepads_joysticks.rst +++ b/tutorials/inputs/controllers_gamepads_joysticks.rst @@ -134,6 +134,35 @@ use ``Input.is_action_pressed()``: held, ``Input.is_action_just_pressed()`` will only return ``true`` for one frame after the button has been pressed. +Local multiplayer setup +----------------------- + +If you're developing a local multiplayer game supporting multiple controllers, +Godot provides the :ref:`PlayerId` enum type to query for actions +triggered by specific players. +By default, you can use methods like ``Input.is_action_just_pressed("ui_left")`` +without any additional argument: that would return true if player one +has just pressed that action. +Player one is by default assigned to the following devices: keyboard, mouse, +touch events, and the first connected controller. +Any additional connected controller will be automatically mapped to their +PlayerId in an incremental way: second controller: player 2 etc. +To check if a specific player just pressed a specific action, you want to use +the previous method with an additional Player Id argument like this: + +.. tabs:: + .. code-tab:: gdscript GDScript + + if Input.is_action_just_pressed("ui_right", false, PLAYER_ID_P2): + # The second player just pressed "ui_right". + + .. code-tab:: csharp + + if (Input.IsActionJustPressed("ui_right", false, PLAYER_ID_P2)) + { + // The second player just pressed "ui_right". + } + Vibration --------- diff --git a/tutorials/inputs/inputevent.rst b/tutorials/inputs/inputevent.rst index f7e88a55052..64072d58c08 100644 --- a/tutorials/inputs/inputevent.rst +++ b/tutorials/inputs/inputevent.rst @@ -45,6 +45,8 @@ You can set up your InputMap under **Project > Project Settings > Input Map** an func _process(delta): if Input.is_action_pressed("ui_right"): # Move right. + if Input.is_action_pressed("ui_select", PLAYER_ID_P2): + # Query second player "ui_select" action. .. code-tab:: csharp @@ -54,6 +56,11 @@ You can set up your InputMap under **Project > Project Settings > Input Map** an { // Move right. } + + if (Input.IsActionPressed("ui_select", PLAYER_ID_P2)) + { + // Query second player "ui_select" action. + } } How does it work? @@ -249,6 +256,41 @@ The Input singleton has a method for this: See :ref:`doc_first_3d_game_input_actions` for a tutorial on adding input actions in the project settings. +Local multiplayer input actions +------------------------------- + +If you're making a local multiplayer game where multiple players share the same keyboard, +you can supply the game back with the appropriate actions just like shown before, +but adding the appropriate :ref:`InputEvent.player ` property: + +.. tabs:: + .. code-tab:: gdscript GDScript + + func _input(event: InputEvent): + if event.keycode == KEY_J && event.is_pressed(): + var ev = InputEventAction.new() + # Set as player 2. + ev.player = PLAYER_ID_P2 + ev.action = "ui_left" + ev.pressed = true + Input.parse_input_event(ev) + + .. code-tab:: csharp + + public override void _Input(InputEvent @event) + { + if (event.keycode == KEY_J && event.is_pressed()) + { + var ev = new InputEventAction(); + // Set as player 2. + ev.Player = PLAYER_ID_P2; + ev.Action = "ui_left"; + ev.Pressed = true; + Input.ParseInputEvent(ev); + } + } + + InputMap --------