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.

531 lines
25 KiB
C#

3 years ago
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<string, bool> handleInputOldState;
private Dictionary<string, bool> handleInputChordedPressed;
private Dictionary<string, bool> handleInputHoldState;
private Dictionary<string, bool> handleInputChordHoldState;
private Dictionary<string, bool> handleInputTimerActive;
private Dictionary<string, bool> handleInputChordedTimerActive;
private Dictionary<string, bool> handleInputState;
private Dictionary<string, float> handleInputTimer;
private Dictionary<string, float> 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<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;
}
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<string, bool>();
if (handleInputChordedPressed == null)
handleInputChordedPressed = new Dictionary<string, bool>();
if (handleInputTimerActive == null)
handleInputTimerActive = new Dictionary<string, bool>();
if (handleInputChordedTimerActive == null)
handleInputChordedTimerActive = new Dictionary<string, bool>();
if (handleInputState == null)
handleInputState = new Dictionary<string, bool>();
if (handleInputHoldState == null)
handleInputHoldState = new Dictionary<string, bool>();
if (handleInputChordHoldState == null)
handleInputChordHoldState = new Dictionary<string, bool>();
if (handleInputTimer == null)
handleInputTimer = new Dictionary<string, float>();
if (handleInputChordedTimer == null)
handleInputChordedTimer = new Dictionary<string, float>();
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();
}
}