First commit for private source control. Older commits available on Github.
This commit is contained in:
560
Assets/Scripts/Framework/Managers/Input/InputManager.cs
Normal file
560
Assets/Scripts/Framework/Managers/Input/InputManager.cs
Normal file
@@ -0,0 +1,560 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BriarQueen.Framework.Coordinators.Events;
|
||||
using BriarQueen.Framework.Events.Gameplay;
|
||||
using BriarQueen.Framework.Events.Input;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
using BriarQueen.Framework.Managers.UI;
|
||||
using BriarQueen.Framework.Services.Game;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.UI;
|
||||
using VContainer;
|
||||
|
||||
namespace BriarQueen.Framework.Managers.Input
|
||||
{
|
||||
public enum DeviceInputType
|
||||
{
|
||||
KeyboardAndMouse,
|
||||
XboxController,
|
||||
PlaystationController,
|
||||
SwitchProController
|
||||
}
|
||||
|
||||
public class InputManager : MonoBehaviour, IDisposable, IManager
|
||||
{
|
||||
[Header("Input")]
|
||||
[SerializeField]
|
||||
private PlayerInput _playerInput;
|
||||
|
||||
[Header("Virtual Cursor")]
|
||||
[SerializeField]
|
||||
private float _controllerCursorSpeed = 1200f;
|
||||
|
||||
[SerializeField]
|
||||
private bool _clampCursorToScreen = true;
|
||||
|
||||
private readonly Dictionary<string, InputAction> _cachedByName = new();
|
||||
|
||||
private InputAction _clickAction;
|
||||
private InputAction _codexAction;
|
||||
private bool _codexShown;
|
||||
private bool _toolScreenShown;
|
||||
|
||||
private GameService _gameService;
|
||||
private EventCoordinator _eventCoordinator;
|
||||
private InputAction _hideHudAction;
|
||||
private bool _hudHidden;
|
||||
|
||||
private bool _initialized;
|
||||
private bool _isPaused;
|
||||
private InputAction _pauseAction;
|
||||
|
||||
private InputAction _pointAction;
|
||||
private InputAction _rightClickAction;
|
||||
private InputAction _openToolsAction;
|
||||
private InputAction _nextToolAction;
|
||||
private InputAction _previousToolAction;
|
||||
private InputAction _nextItemAction;
|
||||
private InputAction _previousItemAction;
|
||||
private InputAction _virtualMouseAction;
|
||||
private InputAction _submitAction;
|
||||
|
||||
private UICursorService _uiCursorService;
|
||||
|
||||
private Vector2 _controllerCursorInput;
|
||||
|
||||
public Vector2 PointerPosition { get; private set; }
|
||||
|
||||
public DeviceInputType DeviceInputType { get; private set; }
|
||||
|
||||
public string ActiveActionMap => _playerInput != null && _playerInput.currentActionMap != null
|
||||
? _playerInput.currentActionMap.name
|
||||
: string.Empty;
|
||||
|
||||
public bool Initialized => _initialized;
|
||||
|
||||
public bool IsPaused => _isPaused;
|
||||
|
||||
public bool UsingControllerCursor => DeviceInputType != DeviceInputType.KeyboardAndMouse;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
PointerPosition = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!_initialized)
|
||||
return;
|
||||
|
||||
UpdateControllerCursor();
|
||||
|
||||
if (_uiCursorService != null && UsingControllerCursor)
|
||||
_uiCursorService.SetVirtualCursorPosition(PointerPosition);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_initialized)
|
||||
return;
|
||||
|
||||
if (_eventCoordinator != null)
|
||||
{
|
||||
_eventCoordinator.Unsubscribe<UIToggleHudEvent>(OnHudStateChanged);
|
||||
_eventCoordinator.Unsubscribe<ToggleCodexEvent>(OnCodexStateChanged);
|
||||
_eventCoordinator.Unsubscribe<ToggleToolScreenEvent>(OnToolScreenStateChanged);
|
||||
}
|
||||
|
||||
UnbindCoreInputs();
|
||||
_initialized = false;
|
||||
}
|
||||
|
||||
[Inject]
|
||||
public void Construct(
|
||||
EventCoordinator eventCoordinator,
|
||||
UICursorService uiCursorService,
|
||||
GameService gameService)
|
||||
{
|
||||
_eventCoordinator = eventCoordinator;
|
||||
_uiCursorService = uiCursorService;
|
||||
_gameService = gameService;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
Debug.Log("[InputManager] Initialize called");
|
||||
|
||||
if (_initialized)
|
||||
{
|
||||
Debug.Log("[InputManager] Already initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_eventCoordinator == null)
|
||||
{
|
||||
Debug.LogWarning("[InputManager] EventCoordinator is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_playerInput == null)
|
||||
{
|
||||
Debug.LogWarning("[InputManager] PlayerInput is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_playerInput.actions == null)
|
||||
{
|
||||
Debug.LogWarning("[InputManager] PlayerInput.actions is null");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log($"[InputManager] Current map before cache: {ActiveActionMap}");
|
||||
|
||||
CacheActions();
|
||||
|
||||
Debug.Log($"[InputManager] Point action: {_pointAction}");
|
||||
Debug.Log($"[InputManager] Click action: {_clickAction}");
|
||||
Debug.Log($"[InputManager] Virtual_Mouse action: {_virtualMouseAction}");
|
||||
|
||||
BindCoreInputs();
|
||||
|
||||
DeviceInputType = GetDeviceInputType(_playerInput);
|
||||
ApplyCursorModeForCurrentScheme();
|
||||
|
||||
_initialized = true;
|
||||
|
||||
Debug.Log("[InputManager] Initialization complete");
|
||||
}
|
||||
|
||||
private void CacheActions()
|
||||
{
|
||||
_cachedByName.Clear();
|
||||
|
||||
_pointAction = CacheAction("Point");
|
||||
_virtualMouseAction = CacheAction("Virtual_Mouse");
|
||||
_pauseAction = CacheAction("Pause");
|
||||
_clickAction = CacheAction("Click");
|
||||
_rightClickAction = CacheAction("Right_Click");
|
||||
_hideHudAction = CacheAction("Hide_HUD");
|
||||
_codexAction = CacheAction("Codex");
|
||||
_openToolsAction = CacheAction("Show_Tools");
|
||||
_nextToolAction = CacheAction("Next_Tool");
|
||||
_previousToolAction = CacheAction("Previous_Tool");
|
||||
_nextItemAction = CacheAction("Next_Item");
|
||||
_previousItemAction = CacheAction("Previous_Item");
|
||||
_submitAction = CacheAction("Submit");
|
||||
}
|
||||
|
||||
private InputAction CacheAction(string actionName)
|
||||
{
|
||||
var action = GetAction(actionName);
|
||||
|
||||
if (action != null && !string.IsNullOrWhiteSpace(action.name))
|
||||
_cachedByName[action.name] = action;
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
private void BindCoreInputs()
|
||||
{
|
||||
if (_pointAction != null)
|
||||
{
|
||||
Debug.Log("[InputManager] Binding Point");
|
||||
|
||||
_pointAction.performed += OnPoint;
|
||||
_pointAction.canceled += OnPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[InputManager] Required action 'Point' not found.");
|
||||
}
|
||||
|
||||
if (_virtualMouseAction != null)
|
||||
{
|
||||
_virtualMouseAction.performed += OnVirtualMouse;
|
||||
_virtualMouseAction.canceled += OnVirtualMouse;
|
||||
}
|
||||
|
||||
if (_pauseAction != null)
|
||||
_pauseAction.performed += OnPause;
|
||||
else
|
||||
Debug.LogWarning("[InputManager] Action 'Pause' not found.");
|
||||
|
||||
if (_clickAction != null)
|
||||
_clickAction.performed += OnClick;
|
||||
else
|
||||
Debug.LogWarning("[InputManager] Action 'Click' not found.");
|
||||
|
||||
if (_rightClickAction != null)
|
||||
_rightClickAction.performed += OnRightClick;
|
||||
else
|
||||
Debug.LogWarning("[InputManager] Action 'Right_Click' not found.");
|
||||
|
||||
if (_hideHudAction != null)
|
||||
_hideHudAction.performed += OnHideHUD;
|
||||
else
|
||||
Debug.LogWarning("[InputManager] Action 'Hide_HUD' not found.");
|
||||
|
||||
if (_codexAction != null)
|
||||
_codexAction.performed += OnCodex;
|
||||
else
|
||||
Debug.LogWarning("[InputManager] Action 'Codex' not found.");
|
||||
|
||||
if (_openToolsAction != null)
|
||||
_openToolsAction.performed += OnOpenTools;
|
||||
else
|
||||
Debug.LogWarning("[InputManager] Action 'Show_Tools' not found.");
|
||||
|
||||
if (_nextToolAction != null)
|
||||
_nextToolAction.performed += OnNextToolClicked;
|
||||
else
|
||||
Debug.LogWarning("[InputManager] Action 'Next_Tool' not found.");
|
||||
|
||||
if (_previousToolAction != null)
|
||||
_previousToolAction.performed += OnPreviousToolClicked;
|
||||
else
|
||||
Debug.LogWarning("[InputManager] Action 'Previous_Tool' not found.");
|
||||
|
||||
if (_nextItemAction != null)
|
||||
_nextItemAction.performed += OnNextItemClicked;
|
||||
else
|
||||
Debug.LogWarning("[InputManager] Action 'Next_Item' not found.");
|
||||
|
||||
if (_previousItemAction != null)
|
||||
_previousItemAction.performed += OnPreviousItemClicked;
|
||||
else
|
||||
Debug.LogWarning("[InputManager] Action 'Previous_Item' not found.");
|
||||
|
||||
if (_playerInput != null)
|
||||
_playerInput.onControlsChanged += OnControlsChanged;
|
||||
}
|
||||
|
||||
private void UnbindCoreInputs()
|
||||
{
|
||||
if (_pointAction != null)
|
||||
{
|
||||
_pointAction.performed -= OnPoint;
|
||||
_pointAction.canceled -= OnPoint;
|
||||
}
|
||||
|
||||
if (_virtualMouseAction != null)
|
||||
{
|
||||
_virtualMouseAction.performed -= OnVirtualMouse;
|
||||
_virtualMouseAction.canceled -= OnVirtualMouse;
|
||||
}
|
||||
|
||||
if (_pauseAction != null)
|
||||
_pauseAction.performed -= OnPause;
|
||||
|
||||
if (_clickAction != null)
|
||||
_clickAction.performed -= OnClick;
|
||||
|
||||
if (_rightClickAction != null)
|
||||
_rightClickAction.performed -= OnRightClick;
|
||||
|
||||
if (_hideHudAction != null)
|
||||
_hideHudAction.performed -= OnHideHUD;
|
||||
|
||||
if (_codexAction != null)
|
||||
_codexAction.performed -= OnCodex;
|
||||
|
||||
if (_openToolsAction != null)
|
||||
_openToolsAction.performed -= OnOpenTools;
|
||||
|
||||
if (_nextToolAction != null)
|
||||
_nextToolAction.performed -= OnNextToolClicked;
|
||||
|
||||
if (_previousToolAction != null)
|
||||
_previousToolAction.performed -= OnPreviousToolClicked;
|
||||
|
||||
if (_nextItemAction != null)
|
||||
_nextItemAction.performed -= OnNextItemClicked;
|
||||
|
||||
if (_previousItemAction != null)
|
||||
_previousItemAction.performed -= OnPreviousItemClicked;
|
||||
|
||||
if (_playerInput != null)
|
||||
_playerInput.onControlsChanged -= OnControlsChanged;
|
||||
}
|
||||
|
||||
private void UpdateControllerCursor()
|
||||
{
|
||||
if (!UsingControllerCursor)
|
||||
return;
|
||||
|
||||
if (_controllerCursorInput.sqrMagnitude <= 0.0001f)
|
||||
return;
|
||||
|
||||
PointerPosition += _controllerCursorInput * (_controllerCursorSpeed * Time.unscaledDeltaTime);
|
||||
|
||||
if (_clampCursorToScreen)
|
||||
{
|
||||
PointerPosition = new Vector2(
|
||||
Mathf.Clamp(PointerPosition.x, 0f, Screen.width),
|
||||
Mathf.Clamp(PointerPosition.y, 0f, Screen.height)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnControlsChanged(PlayerInput playerInput)
|
||||
{ Debug.Log($"Controls changed. Scheme: {playerInput.currentControlScheme}");
|
||||
DeviceInputType = GetDeviceInputType(playerInput);
|
||||
ApplyCursorModeForCurrentScheme();
|
||||
}
|
||||
|
||||
private void ApplyCursorModeForCurrentScheme()
|
||||
{
|
||||
if (_uiCursorService == null)
|
||||
return;
|
||||
|
||||
var useVirtualCursor = UsingControllerCursor;
|
||||
_uiCursorService.SetUseVirtualCursor(useVirtualCursor);
|
||||
|
||||
if (useVirtualCursor)
|
||||
_uiCursorService.SetVirtualCursorPosition(PointerPosition);
|
||||
}
|
||||
|
||||
public void BindPauseForSkip(Action<InputAction.CallbackContext> callback)
|
||||
{
|
||||
if (_pauseAction == null || callback == null)
|
||||
return;
|
||||
|
||||
_pauseAction.performed -= OnPause;
|
||||
_pauseAction.performed += callback;
|
||||
}
|
||||
|
||||
public void ResetPauseBind(Action<InputAction.CallbackContext> callback)
|
||||
{
|
||||
if (_pauseAction == null || callback == null)
|
||||
return;
|
||||
|
||||
_pauseAction.performed -= callback;
|
||||
_pauseAction.performed -= OnPause;
|
||||
_pauseAction.performed += OnPause;
|
||||
}
|
||||
|
||||
public void BindSubmitForStart(Action<InputAction.CallbackContext> callback)
|
||||
{
|
||||
if (_submitAction == null || callback == null)
|
||||
return;
|
||||
|
||||
_submitAction.performed += callback;
|
||||
}
|
||||
|
||||
public void ResetSubmitBind(Action<InputAction.CallbackContext> callback)
|
||||
{
|
||||
if (_submitAction == null || callback == null)
|
||||
return;
|
||||
|
||||
_submitAction.performed -= callback;
|
||||
}
|
||||
|
||||
public void BindAction(string actionName, Action<InputAction.CallbackContext> callback)
|
||||
{
|
||||
if (callback == null)
|
||||
return;
|
||||
|
||||
var action = GetCachedAction(actionName);
|
||||
if (action == null)
|
||||
{
|
||||
Debug.LogWarning($"[InputManager] Action '{actionName}' not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
action.performed -= callback;
|
||||
action.performed += callback;
|
||||
}
|
||||
|
||||
public void UnbindAction(string actionName, Action<InputAction.CallbackContext> callback)
|
||||
{
|
||||
if (callback == null)
|
||||
return;
|
||||
|
||||
var action = GetCachedAction(actionName);
|
||||
if (action == null)
|
||||
{
|
||||
Debug.LogWarning($"[InputManager] Action '{actionName}' not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
action.performed -= callback;
|
||||
}
|
||||
|
||||
private InputAction GetCachedAction(string actionName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(actionName))
|
||||
return null;
|
||||
|
||||
if (_cachedByName.TryGetValue(actionName, out var cached))
|
||||
return cached;
|
||||
|
||||
var action = GetAction(actionName);
|
||||
if (action != null)
|
||||
_cachedByName[actionName] = action;
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
private static DeviceInputType GetDeviceInputType(PlayerInput input)
|
||||
{
|
||||
if (input == null)
|
||||
return DeviceInputType.KeyboardAndMouse;
|
||||
|
||||
return input.currentControlScheme switch
|
||||
{
|
||||
"Keyboard&Mouse" => DeviceInputType.KeyboardAndMouse,
|
||||
"Xbox" => DeviceInputType.XboxController,
|
||||
"Playstation" => DeviceInputType.PlaystationController,
|
||||
"Switch Pro" => DeviceInputType.SwitchProController,
|
||||
_ => DeviceInputType.KeyboardAndMouse
|
||||
};
|
||||
}
|
||||
|
||||
private void OnHudStateChanged(UIToggleHudEvent evt)
|
||||
{
|
||||
_hudHidden = !evt.Show;
|
||||
}
|
||||
|
||||
private void OnCodexStateChanged(ToggleCodexEvent evt)
|
||||
{
|
||||
_codexShown = evt.Shown;
|
||||
}
|
||||
|
||||
private void OnToolScreenStateChanged(ToggleToolScreenEvent evt)
|
||||
{
|
||||
_toolScreenShown = evt.Shown;
|
||||
}
|
||||
|
||||
private void OnHideHUD(InputAction.CallbackContext ctx)
|
||||
{
|
||||
_hudHidden = !_hudHidden;
|
||||
_eventCoordinator?.PublishImmediate(new UIToggleHudEvent(_hudHidden));
|
||||
}
|
||||
|
||||
private void OnPause(InputAction.CallbackContext ctx)
|
||||
{
|
||||
if(_gameService.IsMainMenuSceneLoaded)
|
||||
return;
|
||||
|
||||
_isPaused = !_isPaused;
|
||||
_eventCoordinator?.Publish(new PauseButtonClickedEvent());
|
||||
}
|
||||
|
||||
private void OnCodex(InputAction.CallbackContext ctx)
|
||||
{
|
||||
if(_gameService.IsMainMenuSceneLoaded)
|
||||
return;
|
||||
_codexShown = !_codexShown;
|
||||
_eventCoordinator?.Publish(new ToggleCodexEvent(_codexShown));
|
||||
}
|
||||
|
||||
private void OnClick(InputAction.CallbackContext ctx)
|
||||
{
|
||||
_eventCoordinator?.PublishImmediate(new OnClickEvent(ctx));
|
||||
}
|
||||
|
||||
private void OnRightClick(InputAction.CallbackContext ctx)
|
||||
{
|
||||
_eventCoordinator?.PublishImmediate(new OnRightClickEvent(ctx));
|
||||
}
|
||||
|
||||
private void OnPoint(InputAction.CallbackContext ctx)
|
||||
{
|
||||
PointerPosition = ctx.ReadValue<Vector2>();
|
||||
}
|
||||
|
||||
private void OnVirtualMouse(InputAction.CallbackContext ctx)
|
||||
{
|
||||
_controllerCursorInput = ctx.ReadValue<Vector2>();
|
||||
}
|
||||
|
||||
private void OnOpenTools(InputAction.CallbackContext ctx)
|
||||
{
|
||||
if(_gameService.IsMainMenuSceneLoaded)
|
||||
return;
|
||||
_toolScreenShown = !_toolScreenShown;
|
||||
_eventCoordinator?.Publish(new ToggleToolScreenEvent(_toolScreenShown));
|
||||
}
|
||||
|
||||
private void OnNextToolClicked(InputAction.CallbackContext ctx)
|
||||
{
|
||||
_eventCoordinator?.Publish(new OnNextToolChangedEvent());
|
||||
}
|
||||
|
||||
private void OnPreviousToolClicked(InputAction.CallbackContext ctx)
|
||||
{
|
||||
_eventCoordinator?.Publish(new OnPreviousToolChangedEvent());
|
||||
}
|
||||
|
||||
private void OnNextItemClicked(InputAction.CallbackContext ctx)
|
||||
{
|
||||
_eventCoordinator?.Publish(new OnNextItemClickedEvent());
|
||||
}
|
||||
|
||||
private void OnPreviousItemClicked(InputAction.CallbackContext ctx)
|
||||
{
|
||||
_eventCoordinator?.Publish(new OnPreviousItemClickedEvent());
|
||||
}
|
||||
|
||||
public InputAction GetAction(string actionName)
|
||||
{
|
||||
if (_playerInput == null || _playerInput.actions == null || string.IsNullOrWhiteSpace(actionName))
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
return _playerInput.actions.FindAction(actionName, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user