You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

743 lines
30 KiB
C#

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<string, bool> HandleButtonInputOldState;
public Dictionary<string, bool> HandleButtonChordedPressed;
public Dictionary<string, bool> HandleButtonDoublePressStarted;
public Dictionary<string, bool> HandleButtonTimerActive;
public Dictionary<string, bool> HandleButtonChordedTimerActive;
public Dictionary<string, bool> HandleButtonInputInUse;
public Dictionary<string, float> HandleButtonTimer;
public Dictionary<string, float> 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<RaycastResult>();
UIRaycaster.Raycast(pointer, results);
foreach (var result in results)
{
var navigationOption = result.gameObject.GetComponent<NavigationOption>();
if (navigationOption == null)
{
if (result.gameObject.transform.parent != null && result.gameObject.transform.parent.GetComponent<NavigationOption>() != null)
navigationOption = result.gameObject.transform.parent.GetComponent<NavigationOption>();
}
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<string, bool>();
if (HandleButtonChordedPressed == null)
HandleButtonChordedPressed = new Dictionary<string, bool>();
if (HandleButtonDoublePressStarted == null)
HandleButtonDoublePressStarted = new Dictionary<string, bool>();
if (HandleButtonTimerActive == null)
HandleButtonTimerActive = new Dictionary<string, bool>();
if (HandleButtonChordedTimerActive == null)
HandleButtonChordedTimerActive = new Dictionary<string, bool>();
if (HandleButtonInputInUse == null)
HandleButtonInputInUse = new Dictionary<string, bool>();
if (HandleButtonTimer == null)
HandleButtonTimer = new Dictionary<string, float>();
if (HandleButtonChordedTimer == null)
HandleButtonChordedTimer = new Dictionary<string, float>();
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;
}
}
}
}
}