using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using SiegeSong; using UnityEngine.UI; using UnityEngine.EventSystems; namespace SiegeSong { public class InputManager : MonoBehaviour { public float cameraHorizontalInputState = 0.0f; public float cameraVerticalInputState = 0.0f; public float runVerticalInputState = 0.0f; public float runHorizontalInputState = 0.0f; public float menuVerticalInputState = 0.0f; public float menuHorizontalInputState = 0.0f; public float changeCameraInputState = 0.0f; public bool activateInputState = false; public bool dropInputState = false; public bool crouchInputState = false; public bool menuInputState = false; public bool characterScreenInputState = false; public InputScheme CurrentScheme = InputScheme.Xbox; public InputState CurrentState = InputState.OutGameMenu; public Motor Motor; public CameraManager CameraManager; public InventoryManager InventoryManager; public Selector Selector; public MenuManager MenuManager; public GameObject CursorObject; public CommandConsole CommandConsole; public EventSystem UIEventSystem; public GraphicRaycaster UIRaycaster; public AudioSource AudioSource; private Dictionary handleInputOldState; private Dictionary handleInputChordedPressed; private Dictionary handleInputHoldState; private Dictionary handleInputChordHoldState; private Dictionary handleInputTimerActive; private Dictionary handleInputChordedTimerActive; private Dictionary handleInputState; private Dictionary handleInputTimer; private Dictionary handleInputChordedTimer; private KeyCode acceptKeyboardInput = KeyCode.F; private KeyCode cancelKeyboardInput = KeyCode.LeftControl; private KeyCode dropKeyboardInput = KeyCode.X; private KeyCode RunForwardKeyboardInput = KeyCode.W; private KeyCode RunBackwardKeyboardInput = KeyCode.S; private KeyCode StrafeLeftKeyboardInput = KeyCode.A; private KeyCode StrafeRightKeyboardInput = KeyCode.D; private KeyCode ChangeCameraKeyboardInput = KeyCode.F; private string RotateCameraVerticalKeyboardInput = "Mouse Y"; private string RotateCameraHorizontalKeyboardInput = "Mouse X"; private string menuGamepadInput = "Start"; private string characterScreenGamepadInput = "Back"; private string menuVerticalGamepadInput = "D-Pad Vertical"; private string menuHorizontalGamepadInput = "D-Pad Horizontal"; private string acceptGamepadInput = "A"; private string cancelGamepadInput = "B"; private string dropGamepadInput = "X"; private string useRightGamepadInput = "RT"; private string useLeftGamepadInput = "LT"; private string switchLeftGamepadInput = "LB"; private string SwitchRightGamepadInput = "RB"; private string runGamepadInput = "LeftAnalogVertical"; private string strafeGamepadInput = "LeftAnalogHorizontal"; private string rotateCameraVerticalGamepadInput = "RightAnalogVertical"; private string rotateCameraHorizontalGamepadInput = "RightAnalogHorizontal"; private string changeCameraGamepadInput = "RightStickClick"; private KeyCode menuKeyboardInput = KeyCode.Escape; private KeyCode menuUpKeyboardInput = KeyCode.UpArrow; private KeyCode menuDownKeyboardInput = KeyCode.DownArrow; private KeyCode menuLeftKeyboardInput = KeyCode.LeftArrow; private KeyCode menuRightKeyboardInput = KeyCode.RightArrow; private KeyCode characterScreenKeyboardInput = KeyCode.Tab; private string[] keyboardAxisInputs; private KeyCode[] keyboardButtonInputs; private string[] gamepadAxisInputs; private string[] gamepadButtonInputs; private float inputMin = 0.01f; private float longPressTime = 0.4f; private float holdThresholdTime = 0.8f; private float doublePressDelayTime = 0.1f; void Start() { keyboardAxisInputs = new string[] { RotateCameraVerticalKeyboardInput, RotateCameraHorizontalKeyboardInput }; keyboardButtonInputs = new KeyCode[] { RunForwardKeyboardInput, RunBackwardKeyboardInput, StrafeLeftKeyboardInput, StrafeRightKeyboardInput, ChangeCameraKeyboardInput }; gamepadAxisInputs = new string[] { menuVerticalGamepadInput, menuHorizontalGamepadInput, useRightGamepadInput, useLeftGamepadInput, runGamepadInput, strafeGamepadInput, rotateCameraVerticalGamepadInput, rotateCameraHorizontalGamepadInput }; gamepadButtonInputs = new string[] { characterScreenGamepadInput, acceptGamepadInput, cancelGamepadInput, dropGamepadInput, switchLeftGamepadInput, SwitchRightGamepadInput, changeCameraGamepadInput }; } void Update() { updateInputStates(); updateCurrentInputScheme(); switch (CurrentState) { case InputState.World: handleWorldInput(); break; case InputState.InGameMenu: break; case InputState.OutGameMenu: handleOutGameMenuInput(); break; } } private void updateCurrentInputScheme() { foreach (var xboxInput in gamepadAxisInputs) if (Input.GetAxis(xboxInput) > inputMin) CurrentScheme = InputScheme.Xbox; foreach (var xboxInput in gamepadButtonInputs) if (Input.GetButton(xboxInput)) CurrentScheme = InputScheme.Xbox; foreach (var pcInput in keyboardAxisInputs) if (Input.GetAxis(pcInput) > inputMin) CurrentScheme = InputScheme.PC; foreach (var pcInput in keyboardButtonInputs) if (Input.GetKey(pcInput)) CurrentScheme = InputScheme.PC; if (Input.GetMouseButton(0) || Input.GetMouseButton(1) || Input.GetMouseButton(2)) CurrentScheme = InputScheme.PC; } private void handleOutGameMenuInput() { HandleInput(menuVerticalGamepadInput, Input.GetAxis(menuVerticalGamepadInput), onStartedPressing: Input.GetAxis(menuVerticalGamepadInput) > 0 ? MenuManager.SelectNextIndex : (Input.GetAxis(menuVerticalGamepadInput) == 0 ? EmptyDelegateTarget : MenuManager.SelectPreviousIndex)); HandleInput(acceptGamepadInput, getButtonValueAsFloat(acceptGamepadInput), onShortPress: MenuManager.ActivateSelectedOption); updateCursorLocation(); } private void handleWorldInput() { HandleInput(characterScreenGamepadInput, getButtonValueAsFloat(characterScreenGamepadInput), onShortPress: InventoryManager.OpenInventoryScreen); HandleInput(changeCameraGamepadInput, getButtonValueAsFloat(changeCameraGamepadInput), onShortPress: CameraManager.SwitchCamera); HandleInput(runGamepadInput, Input.GetAxis(runGamepadInput), whilePressing: Motor.Run); HandleInput(strafeGamepadInput, Input.GetAxis(strafeGamepadInput), whilePressing: Motor.Strafe); HandleInput(rotateCameraVerticalGamepadInput, Input.GetAxis(rotateCameraVerticalGamepadInput), whilePressing: CameraManager.RotateVertical); HandleInput(rotateCameraHorizontalGamepadInput, Input.GetAxis(rotateCameraHorizontalGamepadInput), whilePressing: CameraManager.RotateHorizontal); } private float getButtonValueAsFloat(string buttonName) { return Input.GetButton(buttonName) ? 1.0f : 0.0f; } private void updateInputStates() { switch (CurrentScheme) { case InputScheme.Xbox: cameraHorizontalInputState = Input.GetAxis(rotateCameraHorizontalGamepadInput); cameraVerticalInputState = Input.GetAxis(rotateCameraVerticalGamepadInput); runVerticalInputState = Input.GetAxis(runGamepadInput); runHorizontalInputState = Input.GetAxis(strafeGamepadInput); menuVerticalInputState = Input.GetAxis(menuVerticalGamepadInput); menuHorizontalInputState = Input.GetAxis(menuHorizontalGamepadInput); changeCameraInputState = Input.GetAxis(changeCameraGamepadInput); activateInputState = Input.GetButton(acceptGamepadInput); dropInputState = Input.GetButton(dropGamepadInput); crouchInputState = Input.GetButton(cancelGamepadInput); menuInputState = Input.GetButton(menuGamepadInput); characterScreenInputState = Input.GetButton(characterScreenGamepadInput); break; case InputScheme.PC: cameraHorizontalInputState = Input.GetAxis(RotateCameraHorizontalKeyboardInput); cameraVerticalInputState = Input.GetAxis(RotateCameraVerticalKeyboardInput); runVerticalInputState = Input.GetKey(RunForwardKeyboardInput) && !Input.GetKey(RunBackwardKeyboardInput) ? 1.0f : Input.GetKey(RunBackwardKeyboardInput) ? -1.0f : 0.0f; runHorizontalInputState = Input.GetKey(StrafeLeftKeyboardInput) && !Input.GetKey(StrafeRightKeyboardInput) ? 1.0f : Input.GetKey(StrafeRightKeyboardInput) ? -1.0f : 0.0f; menuVerticalInputState = Input.GetKey(menuUpKeyboardInput) && !Input.GetKey(menuDownKeyboardInput) ? 1.0f : Input.GetKey(menuDownKeyboardInput) ? -1.0f : 0.0f; menuHorizontalInputState = Input.GetKey(menuLeftKeyboardInput) && !Input.GetKey(menuRightKeyboardInput) ? 1.0f : Input.GetKey(menuRightKeyboardInput) ? -1.0f : 0.0f; changeCameraInputState = Input.GetKey(ChangeCameraKeyboardInput) ? 1.0f : 0.0f; activateInputState = Input.GetKey(acceptKeyboardInput); dropInputState = Input.GetKey(dropKeyboardInput); crouchInputState = Input.GetKey(cancelKeyboardInput); menuInputState = Input.GetKey(menuKeyboardInput); characterScreenInputState = Input.GetKey(characterScreenKeyboardInput); break; } } private void updateCursorLocation() { if (!CursorObject.activeSelf) CursorObject.SetActive(true); if (Cursor.visible) Cursor.visible = false; CursorObject.transform.position = Input.mousePosition; var pointer = new PointerEventData(UIEventSystem) { position = Input.mousePosition }; var results = new List(); UIRaycaster.Raycast(pointer, results); foreach (var result in results) { var navigationOption = result.gameObject.GetComponent(); if (navigationOption == null) { if (result.gameObject.transform.parent != null && result.gameObject.transform.parent.GetComponent() != null) navigationOption = result.gameObject.transform.parent.GetComponent(); } if (navigationOption != null) { switch (CurrentState) { case InputState.OutGameMenu: if (navigationOption.Type == NavigationButtonType.Row) { if (!MenuManager.SaveLoadSubmenuOpen && !MenuManager.SettingsSubmenuOpen) MenuManager.SelectedIndex = navigationOption.ItemIndex; else MenuManager.SubMenuSelectedIndex = navigationOption.ItemIndex; } break; case InputState.InGameMenu: if (navigationOption.Type == NavigationButtonType.Row) { InventoryManager.SelectedItemIndex = navigationOption.ItemIndex; InventoryManager.UpdateInventoryScreen(); } break; } if (Input.GetMouseButton(0)) { SelectNavigationOption(navigationOption); } } } } public void SelectNavigationOption(NavigationOption navigationOption) { if (CurrentState == InputState.InGameMenu) { switch (navigationOption.Type) { case NavigationButtonType.Tab: InventoryManager.ActiveTab = navigationOption.ItemIndex; break; case NavigationButtonType.Page: InventoryManager.ActivePage = navigationOption.ItemIndex; break; case NavigationButtonType.Row: InventoryManager.ActivateItem(); break; } } else { MenuManager.SelectedIndex = navigationOption.ItemIndex; MenuManager.ActivateSelectedOption(); } } public void HandleInput(string inputName, float inputValue, string chordInputName = "", float chordedInputValue = 0.0f, InputStartPressingDelegate onStartedPressing = null, InputFullyPressedDelegate onFullyPressed = null, InputWhilePressingDelegate whilePressing = null, InputStopPressingDelegate onStoppedPressing = null, InputStartHoldingDelegate onStartedHolding = null, InputWhileHoldingDelegate whileHolding = null, InputStopHoldingDelegate onStoppedHolding = null, InputShortPressDelegate onShortPress = null, InputLongPressDelegate onLongPress = null, ChordedStartPressingDelegate onChordStartedPressing = null, ChordedFullyPressedDelegate onChordFullyPressed = null, ChordedStopPressingDelegate onChordStoppedPressing = null, ChordedWhileHoldingDelegate whileHoldingChord = null, ChordedStartHoldingDelegate onChordStartedHolding = null, ChordedWhilePressingDelegate whilePressingChord = null, ChordedStopHoldingDelegate onChordStoppedHolding = null, ChordedShortPressDelegate onChordShortPress = null, ChordedLongPressDelegate onChordLongPress = null, bool separatelyHandlePressingAndHolding = false, bool separatelyHandleLongPressAndShortPress = false) { if (handleInputOldState == null) handleInputOldState = new Dictionary(); if (handleInputChordedPressed == null) handleInputChordedPressed = new Dictionary(); if (handleInputTimerActive == null) handleInputTimerActive = new Dictionary(); if (handleInputChordedTimerActive == null) handleInputChordedTimerActive = new Dictionary(); if (handleInputState == null) handleInputState = new Dictionary(); if (handleInputHoldState == null) handleInputHoldState = new Dictionary(); if (handleInputChordHoldState == null) handleInputChordHoldState = new Dictionary(); if (handleInputTimer == null) handleInputTimer = new Dictionary(); if (handleInputChordedTimer == null) handleInputChordedTimer = new Dictionary(); if (!handleInputOldState.ContainsKey(inputName)) handleInputOldState.Add(inputName, false); if (!handleInputChordedPressed.ContainsKey(inputName)) handleInputChordedPressed.Add(inputName, false); if (!handleInputTimerActive.ContainsKey(inputName)) handleInputTimerActive.Add(inputName, false); if (!handleInputChordedTimerActive.ContainsKey(inputName)) handleInputChordedTimerActive.Add(inputName, false); if (!handleInputState.ContainsKey(inputName)) handleInputState.Add(inputName, false); if (!handleInputHoldState.ContainsKey(inputName)) handleInputHoldState.Add(inputName, false); if (!handleInputChordHoldState.ContainsKey(inputName)) handleInputChordHoldState.Add(inputName, false); if (!handleInputTimer.ContainsKey(inputName)) handleInputTimer.Add(inputName, 0.0f); if (!handleInputChordedTimer.ContainsKey(inputName)) handleInputChordedTimer.Add(inputName, 0.0f); var inputPressed = inputValue != 0; var chordPressed = chordedInputValue != 0; if (inputPressed) { if (handleInputChordedTimerActive[inputName]) handleInputChordedTimer[inputName] += Time.deltaTime; if (handleInputTimerActive[inputName]) handleInputTimer[inputName] += Time.deltaTime; handleInputState[inputName] = true; if (!handleInputOldState[inputName]) { if (handleInputTimer[inputName] == 0) { if (!chordPressed) { if (onStartedPressing != null) onStartedPressing.Invoke(); } else if (onChordStartedPressing != null) { onChordStartedPressing.Invoke(); } } handleInputTimerActive[inputName] = true; } else if (handleInputTimer[inputName] > holdThresholdTime) { if (!chordPressed) { if (handleInputHoldState[inputName]) { if (whileHolding != null && (whilePressing == null || separatelyHandlePressingAndHolding)) whileHolding.Invoke(inputValue); if (!separatelyHandlePressingAndHolding && whileHolding == null && whilePressing != null) whilePressing.Invoke(inputValue); } else { handleInputHoldState[inputName] = true; if (onStartedHolding != null) onStartedHolding.Invoke(); } } else { if (handleInputChordHoldState[inputName] && whileHoldingChord != null) { whileHoldingChord.Invoke(inputValue); } else { handleInputChordHoldState[inputName] = true; if (onChordStartedHolding != null) onChordStartedHolding.Invoke(); } } } else { if (!chordPressed) { if (whilePressing != null && (whileHolding == null || separatelyHandlePressingAndHolding)) whilePressing.Invoke(inputValue); if (!separatelyHandlePressingAndHolding && whilePressing == null && whileHolding != null) whileHolding.Invoke(inputValue); } else if (whilePressingChord != null) whilePressingChord.Invoke(inputValue); } } else { handleInputState[inputName] = false; handleInputTimerActive[inputName] = false; if (handleInputOldState[inputName]) { if (!handleInputHoldState[inputName] && !handleInputChordHoldState[inputName]) { if (handleInputTimer[inputName] < longPressTime) { if (!chordPressed) { if (onShortPress != null) onShortPress.Invoke(); } else { if (onChordShortPress != null) onChordShortPress.Invoke(); } } else { if (!chordPressed) { if (onLongPress != null && (onShortPress == null || separatelyHandleLongPressAndShortPress)) onLongPress.Invoke(); if (onLongPress == null && onShortPress != null && !separatelyHandleLongPressAndShortPress) onShortPress.Invoke(); } else { if (onChordLongPress != null && (onChordShortPress == null || separatelyHandleLongPressAndShortPress)) onChordLongPress.Invoke(); if (onChordLongPress == null && onChordShortPress != null && !separatelyHandleLongPressAndShortPress) onChordShortPress.Invoke(); } } handleInputTimerActive[inputName] = true; handleInputOldState[inputName] = false; } else { if (handleInputHoldState[inputName] && onStoppedHolding != null) onStoppedHolding.Invoke(); else if (onChordStoppedHolding != null) onChordStoppedHolding.Invoke(); } } handleInputTimer[inputName] = 0; } handleInputOldState[inputName] = handleInputState[inputName]; } public void EmptyDelegateTarget() { return; } public delegate void InputStartPressingDelegate(); public delegate void InputFullyPressedDelegate(); public delegate void InputWhilePressingDelegate(float value); public delegate void InputStopPressingDelegate(); public delegate void InputShortPressDelegate(); public delegate void InputLongPressDelegate(); public delegate void InputStartHoldingDelegate(); public delegate void InputWhileHoldingDelegate(float value); public delegate void InputStopHoldingDelegate(); public delegate void ChordedStartPressingDelegate(); public delegate void ChordedFullyPressedDelegate(); public delegate void ChordedWhilePressingDelegate(float value); public delegate void ChordedStopPressingDelegate(); public delegate void ChordedShortPressDelegate(); public delegate void ChordedLongPressDelegate(); public delegate void ChordedStartHoldingDelegate(); public delegate void ChordedWhileHoldingDelegate(float value); public delegate void ChordedStopHoldingDelegate(); } }