BLOODJOE/Assets/Scripts/Managers/PlayerJoiner.cs

121 lines
3.9 KiB
C#

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<PlayerInput> _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>();
playerStateMachine.controlledPawn = character.GetComponent<Pawn>();
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());
}
}
}