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 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; public Dictionary HandleButtonInputOldState; public Dictionary HandleButtonChordedPressed; public Dictionary HandleButtonDoublePressStarted; public Dictionary HandleButtonTimerActive; public Dictionary HandleButtonChordedTimerActive; public Dictionary HandleButtonInputInUse; public Dictionary HandleButtonTimer; public Dictionary HandleButtonChordedTimer; private string acceptKeyboardInput = "Space"; private string cancelKeyboardInput = "Backspace"; private string RunForwardKeyboardInput = "w"; private string RunBackwardKeyboardInput = "s"; private string StrafeLeftKeyboardInput = "a"; private string StrafeRightKeyboardInput = "d"; private string ChangeCameraKeyboardInput = "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 string menuKeyboardInput = "Escape"; private string characterScreenKeyboardInput = "Tab"; private string[] keyboardAxisInputs; private string[] keyboardButtonInputs; private string[] gamepadAxisInputs; private string[] gamepadButtonInputs; private float inputMin = 0.01f; private float longPressTime = 0.4f; private float doublePressDelayTime = 0.1f; private bool oldActivateState; private bool oldCharacterScreenState; private bool oldMenuState; private bool oldCameraState; private bool oldDropState; private bool oldCrouchState; private bool oldOpenInputState; private bool oldActivateInputState; private bool oldDropInputState; private bool oldDownArrowInputState; private bool oldUpArrowInputState; private bool oldConfirmState; private bool oldRejectState; private float oldVerticalState; private float oldHorizontalState; void Start() { keyboardAxisInputs = new string[] { RotateCameraVerticalKeyboardInput, RotateCameraHorizontalKeyboardInput }; keyboardButtonInputs = new string[] { 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 }; } public InputDirection GetInputDirection(bool leftStick = false) { var stickVerticalGamepad = Input.GetAxis(leftStick ? runGamepadInput : rotateCameraVerticalGamepadInput); var stickHorizontalGamepad = Input.GetAxis(leftStick ? strafeGamepadInput : rotateCameraHorizontalGamepadInput); var up = false; var down = false; var left = false; var right = false; if (stickVerticalGamepad > 0) up = true; if (stickVerticalGamepad < 0) down = true; if (stickHorizontalGamepad > 0) left = true; if (stickHorizontalGamepad < 0) right = true; if (up && left) return InputDirection.TopLeft; if (up && right) return InputDirection.TopRight; if (down && right) return InputDirection.BottomRight; if (down && left) return InputDirection.BottomLeft; if (up) return InputDirection.TopMid; if (down) return InputDirection.BottomMid; if (left) return InputDirection.MidLeft; if (right) return InputDirection.MidRight; return InputDirection.MidMid; } void Update() { if (Input.GetKeyDown("`")) CommandConsole.CommandConsoleOpen = !CommandConsole.CommandConsoleOpen; 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; switch (CurrentState) { case InputState.World: updateWorldInput(); break; case InputState.InGameMenu: updateInGameMenuInput(); break; case InputState.OutGameMenu: updateOutGameMenuInput(); break; } } 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; case InputState.World: 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 if (MenuManager.MenuActive) { MenuManager.ActivateSelectedOption(); } } void updateWorldInput() { var shouldStop = false; var shouldRotate = false; var zooming = false; var strafe = 0.0f; var run = 0.0f; if (CurrentScheme == InputScheme.Xbox) { var cameraHorizontalGamepad = Input.GetAxis(rotateCameraHorizontalGamepadInput); var cameraVerticalGamepad = Input.GetAxis(rotateCameraVerticalGamepadInput); var runVerticalGamepad = Input.GetAxis(runGamepadInput); var runHorizontalGamepad = Input.GetAxis(strafeGamepadInput); var menuVerticalGamepad = Input.GetAxis(menuVerticalGamepadInput); var menuHorizontalGamepad = Input.GetAxis(menuHorizontalGamepadInput); var changeCameraGamepad = Input.GetAxis(changeCameraGamepadInput); var activateGamepad = Input.GetButton(acceptGamepadInput); var dropGamepad = Input.GetButton(dropGamepadInput); var openMenuGamepad = Input.GetButton(characterScreenGamepadInput); var crouchGamepad = Input.GetButton(cancelGamepadInput); var menuGamepad = Input.GetButton(menuGamepadInput); var characterScreenGamepad = Input.GetButton(characterScreenGamepadInput); if (menuGamepad && !oldMenuState) { CurrentState = InputState.OutGameMenu; MenuManager.MenuOpening = true; } if (openMenuGamepad && !oldCharacterScreenState) { CurrentState = InputState.InGameMenu; InventoryManager.OpenInventoryScreen(); } Selector.InteractInputNewState = !oldActivateState && activateGamepad; HandleButtonInput(useRightGamepadInput, Motor.UseRight, null, null, null, null, true); HandleButtonInput(useLeftGamepadInput, Motor.UseLeft, null, null, null, null, true); HandleButtonInput(dropGamepadInput, Motor.UseAbility, null, null, null, null, true); HandleButtonInput(SwitchRightGamepadInput, Motor.NextRightTechnique, Motor.NextRightEquip); HandleButtonInput(switchLeftGamepadInput, Motor.NextLeftTechnique, Motor.NextLeftEquip, Motor.NextAbilityEquip, Motor.NextAbilityTechnique, SwitchRightGamepadInput); HandleButtonInput(changeCameraGamepadInput, CameraManager.SwitchCamera, null, null, null, null, true); if (!InventoryManager.ActivateInputNewState && activateGamepad && !oldActivateState && Motor.UsingStation && Motor.TargetStation != null && Selector.Target == null) Motor.StopUsingStation(Motor.TargetStation); if (Motor != null) { if (runVerticalGamepad > inputMin || runVerticalGamepad < -inputMin) { run = runVerticalGamepad; Motor.Run(runVerticalGamepad); shouldRotate = true; } else { run = 0; Motor.Run(0); } if (runHorizontalGamepad != 0) { strafe = runHorizontalGamepad; Motor.Strafe(runHorizontalGamepad); shouldRotate = true; } else { strafe = 0; Motor.Strafe(0); } switch (CurrentScheme) { case InputScheme.Xbox: break; case InputScheme.PC: break; } if (cameraVerticalGamepad != 0) CameraManager.RotateVertical(cameraVerticalGamepad); else CameraManager.RotateVertical(0); if (cameraHorizontalGamepad != 0) CameraManager.RotateHorizontal(cameraHorizontalGamepad); else CameraManager.RotateHorizontal(0); if (oldCameraState && changeCameraGamepad != 0) { if (runVerticalGamepad != 0) { zooming = true; if (runVerticalGamepad > 0) CameraManager.ZoomOut(); else CameraManager.ZoomIn(); } } if (!zooming && !(runVerticalGamepad > inputMin || runVerticalGamepad < -inputMin) && !(runHorizontalGamepad > inputMin || runHorizontalGamepad < -inputMin)) shouldStop = true; } oldCameraState = changeCameraGamepad != 0; oldActivateState = activateGamepad; oldDropState = dropGamepad; oldCharacterScreenState = openMenuGamepad; oldMenuState = menuGamepad; oldCrouchState = crouchGamepad; } else { var runForward = Input.GetKey(RunForwardKeyboardInput); var runBackward = Input.GetKey(RunBackwardKeyboardInput); var strafeLeft = Input.GetKey(StrafeLeftKeyboardInput); var strafeRight = Input.GetKey(StrafeRightKeyboardInput); var cameraHorizontalKeyboad = Input.GetAxis(RotateCameraHorizontalKeyboardInput); var cameraVerticalKeyboad = Input.GetAxis(RotateCameraVerticalKeyboardInput); var changeCameraKeyboad = Input.GetKeyDown(ChangeCameraKeyboardInput); var characterScreenKeyboard = Input.GetButton(characterScreenKeyboardInput); var menuKeyboard = Input.GetButton(menuKeyboardInput); if (menuKeyboard && !oldMenuState) { CurrentState = InputState.OutGameMenu; MenuManager.MenuOpening = true; } if (characterScreenKeyboard && !oldCharacterScreenState) { CurrentState = InputState.InGameMenu; InventoryManager.OpenInventoryScreen(); } if (Motor != null && CameraManager != null) { if (!changeCameraKeyboad && cameraVerticalKeyboad > inputMin || cameraVerticalKeyboad < -inputMin) CameraManager.RotateVertical(cameraVerticalKeyboad); if (cameraHorizontalKeyboad > inputMin || cameraHorizontalKeyboad < -inputMin) CameraManager.RotateHorizontal(cameraHorizontalKeyboad); if (changeCameraKeyboad) { if (runForward || runBackward) { zooming = true; if (runForward) CameraManager.ZoomOut(); if (runBackward) CameraManager.ZoomIn(); } } if (runForward && !changeCameraKeyboad && !zooming) { run = 1; Motor.Run(1); shouldRotate = true; } else if (!runBackward) { run = 0; Motor.Run(0); } if (runBackward && !changeCameraKeyboad && !zooming) { run = -1; Motor.Run(-1); shouldRotate = true; } else if (!runForward) { run = 0; Motor.Run(0); } if (strafeLeft && !zooming) { strafe = -1; Motor.Strafe(-1); shouldRotate = true; } else if (!strafeRight) { strafe = 0; Motor.Strafe(0); } if (strafeRight && !zooming) { strafe = 1; Motor.Strafe(1); shouldRotate = true; } else if (!strafeLeft) { strafe = 0; Motor.Strafe(0); } if (!runForward && !runBackward && !strafeLeft && !strafeRight) shouldStop = true; } oldCameraState = changeCameraKeyboad; oldCharacterScreenState = characterScreenKeyboard; oldMenuState = menuKeyboard; } if (shouldRotate || (CameraManager.FirstPersonActive && CameraManager.CameraX != 0.0f)) { CameraManager.RealignCamera(true); if (CameraManager.FirstPersonActive && CameraManager.CameraX != 0.0f) Motor.Strafe(0, true); } if (shouldStop) Motor.Stop(); } void updateInGameMenuInput() { var UpArrowInputNewState = false; var DownArrowInputNewState = false; var menuVertical = Input.GetAxis(menuVerticalGamepadInput); var menuHorizontal = Input.GetAxis(menuHorizontalGamepadInput); var activateGamepadInput = Input.GetButton(acceptGamepadInput); var dropGamepadInput = Input.GetButton(this.dropGamepadInput); var openMenuGamepadInput = Input.GetButton(characterScreenGamepadInput); var crouchState = Input.GetButton(cancelGamepadInput); if (crouchState && !oldCrouchState) { InventoryManager.CloseInventoryScreen(); InventoryManager.CloseTransferScreen(); CurrentState = InputState.World; } InventoryManager.ActivateInputNewState = !oldActivateState && activateGamepadInput; InventoryManager.DropInputNewState = !oldDropState && dropGamepadInput; if (menuVertical > inputMin) InventoryManager.UpArrowInputNewState = true; else InventoryManager.UpArrowInputNewState = false; if (menuVertical < -inputMin) InventoryManager.DownArrowInputNewState = true; else InventoryManager.DownArrowInputNewState = false; if (!oldUpArrowInputState && UpArrowInputNewState) { InventoryManager.SelectNextRow(); } if (!oldDownArrowInputState && DownArrowInputNewState) { InventoryManager.SelectPreviousRow(); } if (UpArrowInputNewState) oldUpArrowInputState = true; if (DownArrowInputNewState) oldDownArrowInputState = true; if (!DownArrowInputNewState && !UpArrowInputNewState) { oldUpArrowInputState = false; oldDownArrowInputState = false; } if (oldActivateInputState && !activateGamepadInput) { if (InventoryManager.TransferScreenOpen) InventoryManager.TransferSelectedItem(); else if (InventoryManager.InventoryScreenOpen) InventoryManager.ActivateItem(); } if (oldDropInputState && !dropGamepadInput) { if (InventoryManager.TransferScreenOpen) { InventoryManager.SwitchTransferTarget(); } else if (!InventoryManager.DroppingItem) { InventoryManager.DroppingItem = true; InventoryManager.DropItem(); } } updateCursorLocation(); oldActivateInputState = activateGamepadInput; oldDropInputState = dropGamepadInput; oldVerticalState = menuVertical; oldHorizontalState = menuHorizontal; oldConfirmState = activateGamepadInput; oldRejectState = crouchState; } void updateOutGameMenuInput() { var menuVertical = Input.GetAxis(menuVerticalGamepadInput); var menuHorizontal = Input.GetAxis(menuHorizontalGamepadInput); var activateGamepadInput = Input.GetButton(acceptGamepadInput); var dropGamepadInput = Input.GetButton(this.dropGamepadInput); var openMenuGamepadInput = Input.GetButton(characterScreenGamepadInput); var crouchState = Input.GetButton(cancelGamepadInput); if (oldVerticalState == 0.0f && menuVertical < 0.0f) MenuManager.SelectNextIndex(true); if (oldVerticalState == 0.0f && menuVertical > 0.0f) MenuManager.SelectNextIndex(); if ((!oldConfirmState && activateGamepadInput) || (oldHorizontalState == 0.0f && menuHorizontal > 0)) { MenuManager.ActivateSelectedOption(); if (crouchState && !oldRejectState) MenuManager.ResumeGame(); } updateCursorLocation(); oldVerticalState = menuVertical; oldHorizontalState = menuHorizontal; oldConfirmState = activateGamepadInput; oldRejectState = crouchState; } public delegate void ShortPress(); public delegate void LongPress(); public delegate void ChordedShortPress(); public delegate void ChordedLongPress(); public void HandleButtonInput(string inputName, ShortPress shortPress, LongPress longPress = null, ChordedShortPress chordedShortPress = null, ChordedLongPress chordedLongPress = null, string chordedInput = "", bool isAxis = false, bool chordIsAxis = false) { if (HandleButtonInputOldState == null) HandleButtonInputOldState = new Dictionary(); if (HandleButtonChordedPressed == null) HandleButtonChordedPressed = new Dictionary(); if (HandleButtonDoublePressStarted == null) HandleButtonDoublePressStarted = new Dictionary(); if (HandleButtonTimerActive == null) HandleButtonTimerActive = new Dictionary(); if (HandleButtonChordedTimerActive == null) HandleButtonChordedTimerActive = new Dictionary(); if (HandleButtonInputInUse == null) HandleButtonInputInUse = new Dictionary(); if (HandleButtonTimer == null) HandleButtonTimer = new Dictionary(); if (HandleButtonChordedTimer == null) HandleButtonChordedTimer = new Dictionary(); if (!HandleButtonInputOldState.ContainsKey(inputName)) HandleButtonInputOldState.Add(inputName, false); if (!HandleButtonChordedPressed.ContainsKey(inputName)) HandleButtonChordedPressed.Add(inputName, false); if (!HandleButtonDoublePressStarted.ContainsKey(inputName)) HandleButtonDoublePressStarted.Add(inputName, false); if (!HandleButtonTimerActive.ContainsKey(inputName)) HandleButtonTimerActive.Add(inputName, false); if (!HandleButtonChordedTimerActive.ContainsKey(inputName)) HandleButtonChordedTimerActive.Add(inputName, false); if (!HandleButtonInputInUse.ContainsKey(inputName)) HandleButtonInputInUse.Add(inputName, false); if (!HandleButtonTimer.ContainsKey(inputName)) HandleButtonTimer.Add(inputName, 0.0f); if (!HandleButtonChordedTimer.ContainsKey(inputName)) HandleButtonChordedTimer.Add(inputName, 0.0f); if (HandleButtonChordedTimerActive[inputName]) HandleButtonChordedTimer[inputName] += Time.deltaTime; if (HandleButtonTimerActive[inputName]) HandleButtonTimer[inputName] += Time.deltaTime; var inputValue = isAxis ? Input.GetAxis(inputName) > inputMin : Input.GetButton(inputName); var chordedInputValue = chordedInput != "" && chordedInput != null ? (chordIsAxis ? Input.GetAxis(chordedInput) > inputMin : Input.GetButton(chordedInput)) : false; if (inputValue) { if (!HandleButtonInputInUse[inputName]) HandleButtonInputInUse[inputName] = true; if (!chordedInputValue) { if (HandleButtonInputOldState[inputName] == false) { HandleButtonTimer[inputName] = 0; HandleButtonTimerActive[inputName] = true; } HandleButtonInputOldState[inputName] = true; } } else { HandleButtonInputInUse[inputName] = false; if (HandleButtonInputOldState[inputName]) { HandleButtonInputOldState[inputName] = false; HandleButtonTimerActive[inputName] = false; if (HandleButtonTimer[inputName] > longPressTime && longPress != null) { longPress.Invoke(); } else { shortPress.Invoke(); } } if (HandleButtonInputOldState[inputName] && !chordedInputValue) { if (!HandleButtonChordedPressed[inputName]) { if (HandleButtonDoublePressStarted[inputName] && HandleButtonChordedTimer[inputName] < doublePressDelayTime) HandleButtonChordedTimerActive[inputName] = false; HandleButtonChordedTimer[inputName] = 0; HandleButtonChordedTimerActive[inputName] = true; } HandleButtonChordedPressed[inputName] = true; } else { HandleButtonChordedTimerActive[inputName] = false; if (HandleButtonChordedPressed[inputName]) { if (HandleButtonChordedTimer[inputName] > longPressTime && chordedLongPress != null) { chordedLongPress.Invoke(); } else if (chordedShortPress != null) { chordedShortPress.Invoke(); } HandleButtonChordedTimerActive[inputName] = true; HandleButtonDoublePressStarted[inputName] = true; } HandleButtonChordedTimer[inputName] = 0; HandleButtonChordedPressed[inputName] = false; } } } } }