From 61b79ae4ed38b7f6349e6a037ffe2344eb93e60e Mon Sep 17 00:00:00 2001 From: hzmt Date: Sat, 31 Jan 2026 17:45:45 -0600 Subject: [PATCH] Fixing players so that game pads only control one character --- Assets/Prefabs/Player.prefab | 2 + Assets/Scenes/Level1.unity | 7 ++ Assets/Scripts/PlayerPickupController.cs | 86 ++++++++++++++++++++ Assets/Scripts/PlayerPlatformerController.cs | 86 ++++++++++++++++++++ 4 files changed, 181 insertions(+) diff --git a/Assets/Prefabs/Player.prefab b/Assets/Prefabs/Player.prefab index ac0539b..3b73b79 100644 --- a/Assets/Prefabs/Player.prefab +++ b/Assets/Prefabs/Player.prefab @@ -199,6 +199,7 @@ MonoBehaviour: moveActionName: Move jumpActionName: Jump controlSchemeName: Keyboard&Mouse + gamepadIndex: -1 moveSpeed: 6 jumpImpulse: 10 groundMask: @@ -221,6 +222,7 @@ MonoBehaviour: actionMapName: Player interactActionName: Crouch controlSchemeName: Keyboard&Mouse + gamepadIndex: -1 holdPoint: {fileID: 5569302833446856119} pickupRange: 1 --- !u!1 &6898135930931977916 diff --git a/Assets/Scenes/Level1.unity b/Assets/Scenes/Level1.unity index 3beab9e..eb0166c 100644 --- a/Assets/Scenes/Level1.unity +++ b/Assets/Scenes/Level1.unity @@ -467,6 +467,7 @@ MonoBehaviour: moveActionName: Move jumpActionName: Jump controlSchemeName: Gamepad + gamepadIndex: 0 moveSpeed: 6 jumpImpulse: 8 groundMask: @@ -670,6 +671,7 @@ MonoBehaviour: moveActionName: Move jumpActionName: Jump controlSchemeName: Gamepad + gamepadIndex: 1 moveSpeed: 6 jumpImpulse: 8 groundMask: @@ -873,6 +875,7 @@ MonoBehaviour: moveActionName: Move jumpActionName: Jump controlSchemeName: Gamepad + gamepadIndex: 2 moveSpeed: 6 jumpImpulse: 8 groundMask: @@ -1072,6 +1075,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 3659140714710275197, guid: 414ae949bae840c4589b38dd91c715e0, type: 3} + propertyPath: interactActionName + value: Interact + objectReference: {fileID: 0} - target: {fileID: 3937090937419967315, guid: 414ae949bae840c4589b38dd91c715e0, type: 3} propertyPath: m_Name value: Player diff --git a/Assets/Scripts/PlayerPickupController.cs b/Assets/Scripts/PlayerPickupController.cs index b37da49..969f9e9 100644 --- a/Assets/Scripts/PlayerPickupController.cs +++ b/Assets/Scripts/PlayerPickupController.cs @@ -1,3 +1,4 @@ +using System; using UnityEngine; using UnityEngine.InputSystem; @@ -9,6 +10,8 @@ public class PlayerPickupController : MonoBehaviour private InputActionAsset runtimeActions; private InputAction interactAction; [SerializeField] private string controlSchemeName = ""; + [SerializeField] private int gamepadIndex = -1; + private bool deviceFilterEnabled; [Header("Setup")] public Transform holdPoint; // Empty GameObject above head @@ -29,6 +32,9 @@ public class PlayerPickupController : MonoBehaviour { runtimeActions.bindingMask = InputBinding.MaskByGroup(controlSchemeName); } + deviceFilterEnabled = ShouldFilterDevices(); + ApplyDeviceFilter(); + InputSystem.onDeviceChange += HandleDeviceChange; var map = runtimeActions.FindActionMap(actionMapName, true); interactAction = map.FindAction(interactActionName, true); @@ -53,6 +59,8 @@ public class PlayerPickupController : MonoBehaviour runtimeActions.Disable(); runtimeActions = null; } + + InputSystem.onDeviceChange -= HandleDeviceChange; } private void OnInteractPerformed(InputAction.CallbackContext context) @@ -113,4 +121,82 @@ public class PlayerPickupController : MonoBehaviour heldObject.transform.SetParent(null); heldObject = null; } + + private bool ShouldFilterDevices() + { + return string.Equals(controlSchemeName, "Gamepad", StringComparison.OrdinalIgnoreCase) || gamepadIndex >= 0; + } + + private void ApplyDeviceFilter() + { + if (!deviceFilterEnabled || runtimeActions == null) + { + return; + } + + var targetIndex = ResolveGamepadIndex(); + if (targetIndex < 0) + { + return; + } + + if (Gamepad.all.Count <= targetIndex) + { + runtimeActions.devices = Array.Empty(); + return; + } + + runtimeActions.devices = new InputDevice[] { Gamepad.all[targetIndex] }; + } + + private void HandleDeviceChange(InputDevice device, InputDeviceChange change) + { + if (!deviceFilterEnabled) + { + return; + } + + if (change == InputDeviceChange.Added || change == InputDeviceChange.Removed || change == InputDeviceChange.Reconnected) + { + ApplyDeviceFilter(); + } + } + + private int ResolveGamepadIndex() + { + if (gamepadIndex >= 0) + { + return gamepadIndex; + } + + if (string.IsNullOrWhiteSpace(actionMapName)) + { + return -1; + } + + if (string.Equals(actionMapName, "Player", StringComparison.OrdinalIgnoreCase)) + { + return 0; + } + + var end = actionMapName.Length - 1; + var start = end; + while (start >= 0 && char.IsDigit(actionMapName[start])) + { + start--; + } + + start++; + if (start > end) + { + return -1; + } + + if (!int.TryParse(actionMapName.Substring(start, end - start + 1), out var parsed)) + { + return -1; + } + + return parsed > 0 ? parsed - 1 : -1; + } } diff --git a/Assets/Scripts/PlayerPlatformerController.cs b/Assets/Scripts/PlayerPlatformerController.cs index 0d580a5..2562486 100644 --- a/Assets/Scripts/PlayerPlatformerController.cs +++ b/Assets/Scripts/PlayerPlatformerController.cs @@ -1,3 +1,4 @@ +using System; using UnityEngine; using UnityEngine.InputSystem; @@ -10,6 +11,7 @@ public class PlayerPlatformerController : MonoBehaviour [SerializeField] private string moveActionName = "Move"; [SerializeField] private string jumpActionName = "Jump"; [SerializeField] private string controlSchemeName = ""; + [SerializeField] private int gamepadIndex = -1; [SerializeField] private float moveSpeed = 6f; [SerializeField] private float jumpImpulse = 8f; [SerializeField] private LayerMask groundMask = ~0; @@ -20,6 +22,7 @@ public class PlayerPlatformerController : MonoBehaviour private InputActionAsset runtimeActions; private InputAction moveAction; private InputAction jumpAction; + private bool deviceFilterEnabled; private void Awake() { @@ -40,6 +43,9 @@ public class PlayerPlatformerController : MonoBehaviour { runtimeActions.bindingMask = InputBinding.MaskByGroup(controlSchemeName); } + deviceFilterEnabled = ShouldFilterDevices(); + ApplyDeviceFilter(); + InputSystem.onDeviceChange += HandleDeviceChange; var map = runtimeActions.FindActionMap(actionMapName, true); moveAction = map.FindAction(moveActionName, true); @@ -68,6 +74,8 @@ public class PlayerPlatformerController : MonoBehaviour runtimeActions.Disable(); runtimeActions = null; } + + InputSystem.onDeviceChange -= HandleDeviceChange; } private void FixedUpdate() @@ -96,6 +104,84 @@ public class PlayerPlatformerController : MonoBehaviour body.AddForce(Vector2.up * jumpImpulse, ForceMode2D.Impulse); } + private bool ShouldFilterDevices() + { + return string.Equals(controlSchemeName, "Gamepad", StringComparison.OrdinalIgnoreCase) || gamepadIndex >= 0; + } + + private void ApplyDeviceFilter() + { + if (!deviceFilterEnabled || runtimeActions == null) + { + return; + } + + var targetIndex = ResolveGamepadIndex(); + if (targetIndex < 0) + { + return; + } + + if (Gamepad.all.Count <= targetIndex) + { + runtimeActions.devices = Array.Empty(); + return; + } + + runtimeActions.devices = new InputDevice[] { Gamepad.all[targetIndex] }; + } + + private void HandleDeviceChange(InputDevice device, InputDeviceChange change) + { + if (!deviceFilterEnabled) + { + return; + } + + if (change == InputDeviceChange.Added || change == InputDeviceChange.Removed || change == InputDeviceChange.Reconnected) + { + ApplyDeviceFilter(); + } + } + + private int ResolveGamepadIndex() + { + if (gamepadIndex >= 0) + { + return gamepadIndex; + } + + if (string.IsNullOrWhiteSpace(actionMapName)) + { + return -1; + } + + if (string.Equals(actionMapName, "Player", StringComparison.OrdinalIgnoreCase)) + { + return 0; + } + + var end = actionMapName.Length - 1; + var start = end; + while (start >= 0 && char.IsDigit(actionMapName[start])) + { + start--; + } + + start++; + if (start > end) + { + return -1; + } + + if (!int.TryParse(actionMapName.Substring(start, end - start + 1), out var parsed)) + { + return -1; + } + + return parsed > 0 ? parsed - 1 : -1; + } + private bool IsGrounded() { var bounds = bodyCollider.bounds;