using System.Collections.Generic; using State; using State.GameStateMachine; using State.PlayerStateMachine; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.UI; namespace Managers { public class PlayerJoiner : MonoBehaviour { [SerializeField] private GameStateMachine stateMachine; [SerializeField] private PlayerInputManager playerInputManager; [SerializeField] private InputSystemUIInputModule uiModule; [SerializeField] private GameObject[] characterPrefabs = new GameObject[2]; private readonly List _players = new(); private PlayerInput _currentUIOwner; private void OnEnable() { playerInputManager.onPlayerJoined += HandlePlayerJoined; playerInputManager.onPlayerLeft += HandlePlayerLeft; stateMachine.OnStateChange += HandleStateChanged; } private void OnDisable() { playerInputManager.onPlayerJoined -= HandlePlayerJoined; playerInputManager.onPlayerLeft -= HandlePlayerLeft; stateMachine.OnStateChange -= HandleStateChanged; } private void HandleStateChanged(GameState newState) { switch (newState) { case MainMenu: EnableUIFor(null); break; case PlayLevel: EnableActionMaps(true); break; case Paused: break; default: break; } } private void HandlePlayerJoined(PlayerInput playerInput) { Debug.Log("Player joined!"); _players.Add(playerInput); // TODO: Move all of this to a player spawner var character = Instantiate(characterPrefabs[_players.Count - 1]); var playerStateMachine = playerInput.gameObject.GetComponent(); playerStateMachine.controlledPawn = character.GetComponent(); playerInput.actions.Enable(); } private void HandlePlayerLeft(PlayerInput playerInput) { _players.Remove(playerInput); if(_currentUIOwner == playerInput) _currentUIOwner = null; } private void EnableUIFor(PlayerInput owner) { _currentUIOwner = owner; var asset = uiModule.actionsAsset; if (owner == null) { asset.devices = null; // any device can drive UI (boot) asset.bindingMask = null; } else { asset.devices = owner.devices; // owner's paired devices only asset.bindingMask = InputBinding.MaskByGroup(owner.currentControlScheme); } // Ensure UI actions are enabled asset.FindActionMap("UI", true).Enable(); } private void EnableActionMaps(bool gameplayEnabled) { foreach (var p in _players) { if (gameplayEnabled) { p.ActivateInput(); if (p.currentActionMap?.name != "Player") p.SwitchCurrentActionMap("Player"); } else { p.DeactivateInput(); // disables player actions, keeps device pairing } } } private void ReleaseUIFocus() { var asset = uiModule.actionsAsset; asset.devices = null; asset.bindingMask = null; _currentUIOwner = null; } // Called by UI Button (Resume) or router "Back" when paused. public void ResumeFromPause() { stateMachine.ChangeState(new PlayLevel()); } } }