985 lines
38 KiB
C#
985 lines
38 KiB
C#
#if !UNITY_2018_OR_NEWER && UNITY_EDITOR
|
|
#define AGGRESIVE_CURSOR_LOCK
|
|
#endif
|
|
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using System.Collections.Generic;
|
|
#if UNITY_EDITOR
|
|
using NeoFPS.ScriptGeneration;
|
|
using System;
|
|
#endif
|
|
|
|
namespace NeoFPS
|
|
{
|
|
[CreateAssetMenu(fileName = "FpsManager_Input", menuName = "NeoFPS/Managers/Input Manager", order = NeoFpsMenuPriorities.manager_input)]
|
|
[HelpURL("https://docs.neofps.com/manual/inputref-so-neofpsinputmanager.html")]
|
|
public class NeoFpsInputManager : NeoFpsInputManagerBase
|
|
{
|
|
protected override void Initialise()
|
|
{
|
|
s_CastInstance = this;
|
|
|
|
InitialiseKeyboardLayouts();
|
|
InitialiseGamepads();
|
|
|
|
base.Initialise();
|
|
|
|
m_GamepadRuntime = GetBehaviourProxy<GamepadInput>();
|
|
}
|
|
|
|
private static NeoFpsInputManager s_CastInstance = null;
|
|
|
|
#region INPUT AXES
|
|
|
|
[SerializeField, Tooltip("The horizontal mouse axis in the Unity input settings.")]
|
|
private string m_MouseXAxis = "Mouse X";
|
|
|
|
[SerializeField, Tooltip("The vertical mouse axis in the Unity input settings.")]
|
|
private string m_MouseYAxis = "Mouse Y";
|
|
|
|
[SerializeField, Tooltip("The mouse scroll wheel axis in the Unity input settings.")]
|
|
private string m_MouseScrollAxis = "Mouse ScrollWheel";
|
|
|
|
public static string mouseXAxis
|
|
{
|
|
get { return s_CastInstance.m_MouseXAxis; }
|
|
}
|
|
public static string mouseYAxis
|
|
{
|
|
get { return s_CastInstance.m_MouseYAxis; }
|
|
}
|
|
public static string mouseScrollAxis
|
|
{
|
|
get { return s_CastInstance.m_MouseScrollAxis; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region INPUT BUTTONS
|
|
|
|
#if UNITY_WEBGL
|
|
private const KeyCode k_MenuKey = KeyCode.Tab;
|
|
#else
|
|
private const KeyCode k_MenuKey = KeyCode.Escape;
|
|
#endif
|
|
|
|
public static readonly string[] fixedInputButtons = { "None", "Menu", "Back", "Cancel" };
|
|
|
|
// Fixed buttons include: None (0), Menu (1), Back (2), Cancel (3)
|
|
[SerializeField, Tooltip("The input buttons the game should use.")]
|
|
private InputButtonInfo[] m_InputButtons = { };
|
|
|
|
[SerializeField, Tooltip("The keyboard layout for the default input buttons.")]
|
|
private KeyboardLayout m_DefaultKeyboardLayout = KeyboardLayout.Qwerty;
|
|
|
|
public static string GetButtonDisplayName(FpsInputButton button)
|
|
{
|
|
if (s_CastInstance == null)
|
|
return "No Input";
|
|
else
|
|
{
|
|
if (button < fixedInputButtons.Length)
|
|
return fixedInputButtons[button];
|
|
else
|
|
return s_CastInstance.m_InputButtons[button - fixedInputButtons.Length].displayName;
|
|
}
|
|
}
|
|
|
|
public static InputCategory GetButtonCategory(FpsInputButton button)
|
|
{
|
|
if (s_CastInstance == null || button < fixedInputButtons.Length)
|
|
return InputCategory.Miscellaneous;
|
|
else
|
|
return s_CastInstance.m_InputButtons[button - fixedInputButtons.Length].category;
|
|
}
|
|
|
|
public static KeyBindingContext GetKeyBindingContext(FpsInputButton button)
|
|
{
|
|
if (s_CastInstance == null || button < fixedInputButtons.Length)
|
|
return KeyBindingContext.Default;
|
|
else
|
|
return s_CastInstance.m_InputButtons[button - fixedInputButtons.Length].context;
|
|
}
|
|
|
|
public static KeyCode GetDefaultPrimaryKey(FpsInputButton button, KeyboardLayout layout)
|
|
{
|
|
if (s_CastInstance == null || button < fixedInputButtons.Length)
|
|
return KeyCode.None;
|
|
else
|
|
{
|
|
var result = s_CastInstance.m_InputButtons[button - fixedInputButtons.Length].defaultPrimary;
|
|
if (layout != s_CastInstance.m_DefaultKeyboardLayout)
|
|
result = GetTranslatedKey(result, layout);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
public static KeyCode GetDefaultSecondaryKey(FpsInputButton button, KeyboardLayout layout)
|
|
{
|
|
if (s_CastInstance == null || button < fixedInputButtons.Length)
|
|
return KeyCode.None;
|
|
else
|
|
{
|
|
var result = s_CastInstance.m_InputButtons[button - fixedInputButtons.Length].defaultSecondary;
|
|
if (layout != s_CastInstance.m_DefaultKeyboardLayout)
|
|
result = GetTranslatedKey(result, layout);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
protected override bool CheckForEscapeInput()
|
|
{
|
|
return Input.GetKeyDown(k_MenuKey) || gamepad.GetButtonDown(FpsInputButton.Menu);
|
|
}
|
|
protected override bool CheckForCancelInput()
|
|
{
|
|
return gamepad.GetButtonDown(FpsInputButton.Cancel) || gamepad.GetButtonDown(FpsInputButton.Back);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region KEYBOARD LAYOUTS
|
|
|
|
// s_Layouts is from qwerty, s_ReverseLayouts is to qwerty
|
|
static Dictionary<KeyCode, KeyCode>[] s_Layouts = null;
|
|
static Dictionary<KeyCode, KeyCode>[] s_ReverseLayouts = null;
|
|
|
|
static KeyCode GetTranslatedKey(KeyCode key, KeyboardLayout layout)
|
|
{
|
|
var defaultLayout = s_CastInstance.m_DefaultKeyboardLayout;
|
|
if (layout != defaultLayout)
|
|
{
|
|
// Get qwerty key
|
|
var qwerty = key;
|
|
if (defaultLayout != KeyboardLayout.Qwerty)
|
|
{
|
|
var map = s_ReverseLayouts[(int)defaultLayout - 1];
|
|
if (map.ContainsKey(key))
|
|
qwerty = map[key];
|
|
}
|
|
|
|
// Get translated from qwerty to layout
|
|
if (layout == KeyboardLayout.Qwerty)
|
|
return qwerty;
|
|
else
|
|
{
|
|
var map = s_Layouts[(int)layout - 1];
|
|
if (map.ContainsKey(qwerty))
|
|
return map[qwerty];
|
|
else
|
|
return qwerty;
|
|
}
|
|
}
|
|
else
|
|
return key;
|
|
}
|
|
|
|
static void InitialiseKeyboardLayouts()
|
|
{
|
|
s_Layouts = new Dictionary<KeyCode, KeyCode>[4];
|
|
s_Layouts[0] = GetLayoutAzerty();
|
|
s_Layouts[1] = GetLayoutQwertz();
|
|
s_Layouts[2] = GetLayoutDvorak();
|
|
s_Layouts[3] = GetLayoutColemak();
|
|
|
|
// Create reverse maps
|
|
s_ReverseLayouts = new Dictionary<KeyCode, KeyCode>[s_Layouts.Length];
|
|
for (int i = 0; i < s_Layouts.Length; ++i)
|
|
{
|
|
s_ReverseLayouts[i] = new Dictionary<KeyCode, KeyCode>();
|
|
foreach (var pair in s_Layouts[i])
|
|
s_ReverseLayouts[i].Add(pair.Value, pair.Key);
|
|
}
|
|
}
|
|
|
|
static Dictionary<KeyCode, KeyCode> GetLayoutAzerty()
|
|
{
|
|
var layout = new Dictionary<KeyCode, KeyCode>();
|
|
layout.Add(KeyCode.Q, KeyCode.A);
|
|
layout.Add(KeyCode.W, KeyCode.Z);
|
|
layout.Add(KeyCode.E, KeyCode.E);
|
|
layout.Add(KeyCode.R, KeyCode.R);
|
|
layout.Add(KeyCode.T, KeyCode.T);
|
|
layout.Add(KeyCode.Y, KeyCode.Y);
|
|
layout.Add(KeyCode.U, KeyCode.U);
|
|
layout.Add(KeyCode.I, KeyCode.I);
|
|
layout.Add(KeyCode.O, KeyCode.O);
|
|
layout.Add(KeyCode.P, KeyCode.P);
|
|
|
|
layout.Add(KeyCode.A, KeyCode.Q);
|
|
layout.Add(KeyCode.S, KeyCode.S);
|
|
layout.Add(KeyCode.D, KeyCode.D);
|
|
layout.Add(KeyCode.F, KeyCode.F);
|
|
layout.Add(KeyCode.G, KeyCode.G);
|
|
layout.Add(KeyCode.H, KeyCode.H);
|
|
layout.Add(KeyCode.J, KeyCode.J);
|
|
layout.Add(KeyCode.K, KeyCode.K);
|
|
layout.Add(KeyCode.L, KeyCode.L);
|
|
layout.Add(KeyCode.Semicolon, KeyCode.M);
|
|
|
|
layout.Add(KeyCode.Z, KeyCode.W);
|
|
layout.Add(KeyCode.X, KeyCode.X);
|
|
layout.Add(KeyCode.C, KeyCode.C);
|
|
layout.Add(KeyCode.V, KeyCode.V);
|
|
layout.Add(KeyCode.B, KeyCode.B);
|
|
layout.Add(KeyCode.N, KeyCode.N);
|
|
layout.Add(KeyCode.M, KeyCode.Comma);
|
|
return layout;
|
|
}
|
|
|
|
static Dictionary<KeyCode, KeyCode> GetLayoutQwertz()
|
|
{
|
|
var layout = new Dictionary<KeyCode, KeyCode>();
|
|
layout.Add(KeyCode.Q, KeyCode.Q);
|
|
layout.Add(KeyCode.W, KeyCode.W);
|
|
layout.Add(KeyCode.E, KeyCode.E);
|
|
layout.Add(KeyCode.R, KeyCode.R);
|
|
layout.Add(KeyCode.T, KeyCode.T);
|
|
layout.Add(KeyCode.Y, KeyCode.Z);
|
|
layout.Add(KeyCode.U, KeyCode.U);
|
|
layout.Add(KeyCode.I, KeyCode.I);
|
|
layout.Add(KeyCode.O, KeyCode.O);
|
|
layout.Add(KeyCode.P, KeyCode.P);
|
|
|
|
layout.Add(KeyCode.A, KeyCode.A);
|
|
layout.Add(KeyCode.S, KeyCode.S);
|
|
layout.Add(KeyCode.D, KeyCode.D);
|
|
layout.Add(KeyCode.F, KeyCode.F);
|
|
layout.Add(KeyCode.G, KeyCode.G);
|
|
layout.Add(KeyCode.H, KeyCode.H);
|
|
layout.Add(KeyCode.J, KeyCode.J);
|
|
layout.Add(KeyCode.K, KeyCode.K);
|
|
layout.Add(KeyCode.L, KeyCode.L);
|
|
|
|
layout.Add(KeyCode.Z, KeyCode.Y);
|
|
layout.Add(KeyCode.X, KeyCode.X);
|
|
layout.Add(KeyCode.C, KeyCode.C);
|
|
layout.Add(KeyCode.V, KeyCode.V);
|
|
layout.Add(KeyCode.B, KeyCode.B);
|
|
layout.Add(KeyCode.N, KeyCode.N);
|
|
layout.Add(KeyCode.M, KeyCode.M);
|
|
return layout;
|
|
}
|
|
|
|
static Dictionary<KeyCode, KeyCode> GetLayoutDvorak()
|
|
{
|
|
var layout = new Dictionary<KeyCode, KeyCode>();
|
|
layout.Add(KeyCode.Q, KeyCode.Quote);
|
|
layout.Add(KeyCode.W, KeyCode.Comma);
|
|
layout.Add(KeyCode.E, KeyCode.Period);
|
|
layout.Add(KeyCode.R, KeyCode.P);
|
|
layout.Add(KeyCode.T, KeyCode.Y);
|
|
layout.Add(KeyCode.Y, KeyCode.F);
|
|
layout.Add(KeyCode.U, KeyCode.G);
|
|
layout.Add(KeyCode.I, KeyCode.C);
|
|
layout.Add(KeyCode.O, KeyCode.R);
|
|
layout.Add(KeyCode.P, KeyCode.L);
|
|
|
|
layout.Add(KeyCode.A, KeyCode.A);
|
|
layout.Add(KeyCode.S, KeyCode.O);
|
|
layout.Add(KeyCode.D, KeyCode.E);
|
|
layout.Add(KeyCode.F, KeyCode.U);
|
|
layout.Add(KeyCode.G, KeyCode.I);
|
|
layout.Add(KeyCode.H, KeyCode.D);
|
|
layout.Add(KeyCode.J, KeyCode.H);
|
|
layout.Add(KeyCode.K, KeyCode.T);
|
|
layout.Add(KeyCode.L, KeyCode.N);
|
|
layout.Add(KeyCode.Semicolon, KeyCode.S);
|
|
|
|
layout.Add(KeyCode.Z, KeyCode.Q);
|
|
layout.Add(KeyCode.X, KeyCode.J);
|
|
layout.Add(KeyCode.C, KeyCode.K);
|
|
layout.Add(KeyCode.V, KeyCode.X);
|
|
layout.Add(KeyCode.B, KeyCode.B);
|
|
layout.Add(KeyCode.N, KeyCode.M);
|
|
layout.Add(KeyCode.M, KeyCode.W);
|
|
layout.Add(KeyCode.Comma, KeyCode.V);
|
|
layout.Add(KeyCode.Period, KeyCode.Z);
|
|
return layout;
|
|
}
|
|
|
|
static Dictionary<KeyCode, KeyCode> GetLayoutColemak()
|
|
{
|
|
var layout = new Dictionary<KeyCode, KeyCode>();
|
|
layout.Add(KeyCode.Q, KeyCode.Q);
|
|
layout.Add(KeyCode.W, KeyCode.W);
|
|
layout.Add(KeyCode.E, KeyCode.F);
|
|
layout.Add(KeyCode.R, KeyCode.P);
|
|
layout.Add(KeyCode.T, KeyCode.G);
|
|
layout.Add(KeyCode.Y, KeyCode.J);
|
|
layout.Add(KeyCode.U, KeyCode.L);
|
|
layout.Add(KeyCode.I, KeyCode.U);
|
|
layout.Add(KeyCode.O, KeyCode.Y);
|
|
layout.Add(KeyCode.P, KeyCode.Semicolon);
|
|
|
|
layout.Add(KeyCode.A, KeyCode.A);
|
|
layout.Add(KeyCode.S, KeyCode.R);
|
|
layout.Add(KeyCode.D, KeyCode.S);
|
|
layout.Add(KeyCode.F, KeyCode.T);
|
|
layout.Add(KeyCode.G, KeyCode.D);
|
|
layout.Add(KeyCode.H, KeyCode.H);
|
|
layout.Add(KeyCode.J, KeyCode.N);
|
|
layout.Add(KeyCode.K, KeyCode.E);
|
|
layout.Add(KeyCode.L, KeyCode.I);
|
|
layout.Add(KeyCode.Semicolon, KeyCode.O);
|
|
|
|
layout.Add(KeyCode.Z, KeyCode.Z);
|
|
layout.Add(KeyCode.X, KeyCode.X);
|
|
layout.Add(KeyCode.C, KeyCode.C);
|
|
layout.Add(KeyCode.V, KeyCode.V);
|
|
layout.Add(KeyCode.B, KeyCode.B);
|
|
layout.Add(KeyCode.N, KeyCode.K);
|
|
layout.Add(KeyCode.M, KeyCode.M);
|
|
return layout;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GAMEPADS
|
|
|
|
[SerializeField, Tooltip("The different gamepad control layouts")]
|
|
private GamepadProfile[] m_GamepadProfiles = { };
|
|
|
|
const int k_GamepadIndexXbox360 = 0;
|
|
const int k_GamepadIndexXboxOne = 1;
|
|
const int k_GamepadIndexPS4 = 2;
|
|
const int k_NumSupportedGamepads = 3;
|
|
|
|
private GamepadUnityInputs[] m_GamepadUnityInputs = { };
|
|
private int m_CurrentGamepadIndex = -1;
|
|
|
|
public static GamepadProfile[] gamepadProfiles
|
|
{
|
|
get { return s_CastInstance.m_GamepadProfiles; }
|
|
}
|
|
|
|
protected override bool GetIsGamepadConnected()
|
|
{
|
|
return m_CurrentGamepadIndex != -1;
|
|
}
|
|
|
|
protected override string GetConnectedGamepad()
|
|
{
|
|
if (m_CurrentGamepadIndex == -1)
|
|
return string.Empty;
|
|
else
|
|
return m_GamepadProfiles[m_CurrentGamepadIndex].name;
|
|
}
|
|
|
|
public static GamepadUnityInputs connectedGamepadInputs
|
|
{
|
|
get
|
|
{
|
|
if (s_CastInstance.m_CurrentGamepadIndex == -1)
|
|
return null;
|
|
else
|
|
return s_CastInstance.m_GamepadUnityInputs[s_CastInstance.m_CurrentGamepadIndex];
|
|
}
|
|
}
|
|
|
|
protected override int GetNumGamepadProfiles()
|
|
{
|
|
return gamepadProfiles.Length;
|
|
}
|
|
|
|
protected override string GetGamepadProfileNameInteral(int index)
|
|
{
|
|
return gamepadProfiles[index].name;
|
|
}
|
|
|
|
private GamepadInput m_GamepadRuntime = null;
|
|
public static GamepadInput gamepad
|
|
{
|
|
get
|
|
{
|
|
if (s_CastInstance != null)
|
|
return s_CastInstance.m_GamepadRuntime;
|
|
else
|
|
return null;
|
|
}
|
|
}
|
|
|
|
void OnValidate()
|
|
{
|
|
#if UNITY_EDITOR
|
|
foreach (var p in m_GamepadProfiles)
|
|
p.OnValidate();
|
|
#endif
|
|
}
|
|
|
|
void InitialiseGamepads()
|
|
{
|
|
m_GamepadUnityInputs = new GamepadUnityInputs[k_NumSupportedGamepads];
|
|
|
|
// Mappings based on information from: https://wiki.unity3d.com/index.php?title=Xbox360Controller
|
|
// Annoyingly, axes and buttons aren't consistent across platforms so we need per-platform profiles
|
|
// More will be added if requested (eg. consoles)
|
|
|
|
#if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
|
|
|
|
var xbox360 = new GamepadUnityInputs(
|
|
"XBox 360", // Name
|
|
"Gamepad Axis 1", "Gamepad Axis 2", // Left analogue
|
|
"Gamepad Axis 3", "Gamepad Axis 4", // Right analogue
|
|
"", "", // Gyro
|
|
new string[]
|
|
{
|
|
"Gamepad Button 16", //ButtonAorX
|
|
"Gamepad Button 17", //ButtonBorCircle
|
|
"Gamepad Button 18", //ButtonXorSquare
|
|
"Gamepad Button 19", //ButtonYorTriangle
|
|
"Gamepad Button 13", //LBumper
|
|
"Gamepad AxisBtn 5", //LTrigger
|
|
"Gamepad Button 14", //RBumper
|
|
"Gamepad AxisBtn 6", //RTrigger
|
|
"Gamepad Button 5", //DPad_Up
|
|
"Gamepad Button 6", //DPad_Down
|
|
"Gamepad Button 7", //DPad_Left
|
|
"Gamepad Button 8", //DPad_Right
|
|
"Gamepad Button 11", //AnaloguePressL
|
|
"Gamepad Button 12", //AnaloguePressR
|
|
"Gamepad Button 9", //Start
|
|
"Gamepad Button 10" //Select
|
|
});
|
|
|
|
var xboxOne = new GamepadUnityInputs(
|
|
"XBox One", // Name
|
|
"Gamepad Axis 1", "Gamepad Axis 2", // Left analogue
|
|
"Gamepad Axis 3", "Gamepad Axis 4", // Right analogue
|
|
"", "", // Gyro
|
|
new string[]
|
|
{
|
|
"Gamepad Button 16", //ButtonAorX
|
|
"Gamepad Button 17", //ButtonBorCircle
|
|
"Gamepad Button 18", //ButtonXorSquare
|
|
"Gamepad Button 19", //ButtonYorTriangle
|
|
"Gamepad Button 13", //LBumper
|
|
"Gamepad AxisBtn 5", //LTrigger
|
|
"Gamepad Button 14", //RBumper
|
|
"Gamepad AxisBtn 6", //RTrigger
|
|
"Gamepad Button 5", //DPad_Up
|
|
"Gamepad Button 6", //DPad_Down
|
|
"Gamepad Button 7", //DPad_Left
|
|
"Gamepad Button 8", //DPad_Right
|
|
"Gamepad Button 11", //AnaloguePressL
|
|
"Gamepad Button 12", //AnaloguePressR
|
|
"Gamepad Button 9", //Start
|
|
"Gamepad Button 10" //Select
|
|
});
|
|
|
|
var ps4 = new GamepadUnityInputs(
|
|
"Playstation Dualshock 4", // Name
|
|
"Gamepad Axis 1", "Gamepad AxisInv 2", // Left analogue
|
|
"Gamepad Axis 3", "Gamepad AxisInv 4", // Right analogue
|
|
"", "", // Gyro
|
|
new string[]
|
|
{
|
|
"Gamepad Button 1", //ButtonAorX
|
|
"Gamepad Button 2", //ButtonBorCircle
|
|
"Gamepad Button 0", //ButtonXorSquare
|
|
"Gamepad Button 3", //ButtonYorTriangle
|
|
"Gamepad Button 4", //LBumper
|
|
"Gamepad Button 6", //LTrigger
|
|
"Gamepad Button 5", //RBumper
|
|
"Gamepad Button 7", //RTrigger
|
|
"Gamepad AxisBtn 8", //DPad_Up
|
|
"Gamepad AxisBtnInv 8", //DPad_Down
|
|
"Gamepad AxisBtnInv 7", //DPad_Left
|
|
"Gamepad AxisBtn 7", //DPad_Right
|
|
"Gamepad Button 10", //AnaloguePressL
|
|
"Gamepad Button 11", //AnaloguePressR
|
|
"Gamepad Button 9", //Start
|
|
"Gamepad Button 13" //Select
|
|
});
|
|
|
|
#elif UNITY_STANDALONE_LINUX || UNITY_EDITOR_LINUX
|
|
|
|
var xbox360 = new GamepadUnityInputs(
|
|
"XBox 360", // Name
|
|
"Gamepad Axis 1", "Gamepad Axis 2", // Left analogue
|
|
"Gamepad Axis 4", "Gamepad Axis 5", // Right analogue
|
|
"", "", // Gyro
|
|
new string[]
|
|
{
|
|
"Gamepad Button 0", //ButtonAorX
|
|
"Gamepad Button 1", //ButtonBorCircle
|
|
"Gamepad Button 2", //ButtonXorSquare
|
|
"Gamepad Button 3", //ButtonYorTriangle
|
|
"Gamepad Button 4", //LBumper
|
|
"Gamepad AxisBtn 3", //LTrigger
|
|
"Gamepad Button 5", //RBumper
|
|
"Gamepad AxisBtn 6", //RTrigger
|
|
"Gamepad Button 13", //DPad_Up
|
|
"Gamepad Button 14", //DPad_Down
|
|
"Gamepad Button 11", //DPad_Left
|
|
"Gamepad Button 12", //DPad_Right
|
|
"Gamepad Button 9", //AnaloguePressL
|
|
"Gamepad Button 10", //AnaloguePressR
|
|
"Gamepad Button 7", //Start
|
|
"Gamepad Button 6" //Select
|
|
});
|
|
|
|
var xboxOne = new GamepadUnityInputs(
|
|
"XBox One", // Name
|
|
"Gamepad Axis 1", "Gamepad Axis 2", // Left analogue
|
|
"Gamepad Axis 4", "Gamepad Axis 5", // Right analogue
|
|
"", "", // Gyro
|
|
new string[]
|
|
{
|
|
"Gamepad Button 0", //ButtonAorX
|
|
"Gamepad Button 1", //ButtonBorCircle
|
|
"Gamepad Button 2", //ButtonXorSquare
|
|
"Gamepad Button 3", //ButtonYorTriangle
|
|
"Gamepad Button 4", //LBumper
|
|
"Gamepad AxisBtn 3", //LTrigger
|
|
"Gamepad Button 5", //RBumper
|
|
"Gamepad AxisBtn 6", //RTrigger
|
|
"Gamepad Button 13", //DPad_Up
|
|
"Gamepad Button 14", //DPad_Down
|
|
"Gamepad Button 11", //DPad_Left
|
|
"Gamepad Button 12", //DPad_Right
|
|
"Gamepad Button 9", //AnaloguePressL
|
|
"Gamepad Button 10", //AnaloguePressR
|
|
"Gamepad Button 7", //Start
|
|
"Gamepad Button 6" //Select
|
|
});
|
|
|
|
var ps4 = new GamepadUnityInputs(
|
|
"Playstation Dualshock 4", // Name
|
|
"Gamepad Axis 1", "Gamepad AxisInv 2", // Left analogue
|
|
"Gamepad Axis 3", "Gamepad AxisInv 6", // Right analogue
|
|
"", "", // Gyro
|
|
new string[]
|
|
{
|
|
"Gamepad Button 1", //ButtonAorX
|
|
"Gamepad Button 2", //ButtonBorCircle
|
|
"Gamepad Button 0", //ButtonXorSquare
|
|
"Gamepad Button 3", //ButtonYorTriangle
|
|
"Gamepad Button 4", //LBumper
|
|
"Gamepad Button 6", //LTrigger
|
|
"Gamepad Button 5", //RBumper
|
|
"Gamepad Button 7", //RTrigger
|
|
"Gamepad AxisBtn 8", //DPad_Up
|
|
"Gamepad AxisBtnInv 8", //DPad_Down
|
|
"Gamepad AxisBtnInv 7", //DPad_Left
|
|
"Gamepad AxisBtn 7", //DPad_Right
|
|
"Gamepad Button 10", //AnaloguePressL
|
|
"Gamepad Button 11", //AnaloguePressR
|
|
"Gamepad Button 9", //Start
|
|
"Gamepad Button 13" //Select
|
|
});
|
|
|
|
#else // WINDOWS (default)
|
|
|
|
var xbox360 = new GamepadUnityInputs(
|
|
"XBox 360", // Name
|
|
"Gamepad Axis 1", "Gamepad AxisInv 2", // Left analogue
|
|
"Gamepad Axis 4", "Gamepad AxisInv 5", // Right analogue
|
|
"", "", // Gyro
|
|
new string[]
|
|
{
|
|
"Gamepad Button 0", //ButtonAorCross
|
|
"Gamepad Button 1", //ButtonBorCircle
|
|
"Gamepad Button 2", //ButtonXorSquare
|
|
"Gamepad Button 3", //ButtonYorTriangle
|
|
"Gamepad Button 4", //LBumper
|
|
"Gamepad AxisBtn 9", //LTrigger
|
|
"Gamepad Button 5", //RBumper
|
|
"Gamepad AxisBtn 10", //RTrigger
|
|
"Gamepad AxisBtn 7", //DPad_Up
|
|
"Gamepad AxisBtnInv 7", //DPad_Down
|
|
"Gamepad AxisBtnInv 6", //DPad_Left
|
|
"Gamepad AxisBtn 6", //DPad_Right
|
|
"Gamepad Button 8", //AnaloguePressL
|
|
"Gamepad Button 9", //AnaloguePressR
|
|
"Gamepad Button 7", //Start
|
|
"Gamepad Button 6" //Select
|
|
});
|
|
|
|
var xboxOne = new GamepadUnityInputs(
|
|
"XBox One", // Name
|
|
"Gamepad Axis 1", "Gamepad AxisInv 2", // Left analogue
|
|
"Gamepad Axis 4", "Gamepad AxisInv 5", // Right analogue
|
|
"", "", // Gyro
|
|
new string[]
|
|
{
|
|
"Gamepad Button 0", //ButtonAorCross
|
|
"Gamepad Button 1", //ButtonBorCircle
|
|
"Gamepad Button 2", //ButtonXorSquare
|
|
"Gamepad Button 3", //ButtonYorTriangle
|
|
"Gamepad Button 4", //LBumper
|
|
"Gamepad AxisBtn 9", //LTrigger
|
|
"Gamepad Button 5", //RBumper
|
|
"Gamepad AxisBtn 10", //RTrigger
|
|
"Gamepad AxisBtn 7", //DPad_Up
|
|
"Gamepad AxisBtnInv 7", //DPad_Down
|
|
"Gamepad AxisBtnInv 6", //DPad_Left
|
|
"Gamepad AxisBtn 6", //DPad_Right
|
|
"Gamepad Button 8", //AnaloguePressL
|
|
"Gamepad Button 9", //AnaloguePressR
|
|
"Gamepad Button 7", //Start
|
|
"Gamepad Button 6" //Select
|
|
});
|
|
|
|
var ps4 = new GamepadUnityInputs(
|
|
"Playstation Dualshock 4", // Name
|
|
"Gamepad Axis 1", "Gamepad AxisInv 2", // Left analogue
|
|
"Gamepad Axis 3", "Gamepad AxisInv 6", // Right analogue
|
|
"", "", // Gyro
|
|
new string[]
|
|
{
|
|
"Gamepad Button 1", //ButtonAorCross
|
|
"Gamepad Button 2", //ButtonBorCircle
|
|
"Gamepad Button 0", //ButtonXorSquare
|
|
"Gamepad Button 3", //ButtonYorTriangle
|
|
"Gamepad Button 4", //LBumper
|
|
"Gamepad Button 6", //LTrigger
|
|
"Gamepad Button 5", //RBumper
|
|
"Gamepad Button 7", //RTrigger
|
|
"Gamepad AxisBtn 8", //DPad_Up
|
|
"Gamepad AxisBtnInv 8", //DPad_Down
|
|
"Gamepad AxisBtnInv 7", //DPad_Left
|
|
"Gamepad AxisBtn 7", //DPad_Right
|
|
"Gamepad Button 10", //AnaloguePressL
|
|
"Gamepad Button 11", //AnaloguePressR
|
|
"Gamepad Button 9", //Start
|
|
"Gamepad Button 13" //Select
|
|
});
|
|
#endif
|
|
|
|
// Apply the profiles
|
|
m_GamepadUnityInputs[k_GamepadIndexXbox360] = xbox360;
|
|
m_GamepadUnityInputs[k_GamepadIndexXboxOne] = xboxOne;
|
|
m_GamepadUnityInputs[k_GamepadIndexPS4] = ps4;
|
|
}
|
|
|
|
void CheckGamepads()
|
|
{
|
|
int oldIndex = m_CurrentGamepadIndex;
|
|
m_CurrentGamepadIndex = -1;
|
|
|
|
var joystickNames = Input.GetJoystickNames();
|
|
for (int i = 0; i < joystickNames.Length; ++i)
|
|
{
|
|
if (string.IsNullOrEmpty(joystickNames[i]))
|
|
continue;
|
|
|
|
string lower = joystickNames[i].ToLower();
|
|
|
|
// Check if PS4 controller
|
|
if (joystickNames[i] == "Wireless Controller" ||
|
|
joystickNames[i] == "Sony Interactive Entertainment Wireless Controller" ||
|
|
joystickNames[i] == "Sony Computer Entertainment Wireless Controller" ||
|
|
joystickNames[i] == "Sony Interactive Entertainment DUALSHOCK®4 USB Wireless Adaptor")
|
|
{
|
|
m_CurrentGamepadIndex = k_GamepadIndexPS4;
|
|
break;
|
|
}
|
|
|
|
// Check if XBox controller
|
|
if (lower.Contains("xbox"))
|
|
{
|
|
if (lower.Contains("xbox one"))
|
|
m_CurrentGamepadIndex = k_GamepadIndexXboxOne;
|
|
else
|
|
m_CurrentGamepadIndex = k_GamepadIndexXbox360;
|
|
break;
|
|
}
|
|
|
|
// Check if XBox Series controller (wireless)
|
|
if (joystickNames[i] == "Ű" ||
|
|
joystickNames[i] == "耀")
|
|
{
|
|
m_CurrentGamepadIndex = k_GamepadIndexXboxOne;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Fire changed event if relevant
|
|
if (m_CurrentGamepadIndex != oldIndex)
|
|
OnGamepadConnectedChanged(m_CurrentGamepadIndex != -1);
|
|
}
|
|
|
|
protected override void OnDestroy()
|
|
{
|
|
base.OnDestroy();
|
|
|
|
if (m_GamepadRuntime != null)
|
|
{
|
|
Destroy(m_GamepadRuntime);
|
|
m_GamepadRuntime = null;
|
|
}
|
|
}
|
|
|
|
public class GamepadInput : MonoBehaviour
|
|
{
|
|
private ButtonState[] m_States = null;
|
|
private bool m_UseGamepad = false;
|
|
private int m_ProfileIndex = 0;
|
|
|
|
private enum ButtonState
|
|
{
|
|
Up,
|
|
Pressed,
|
|
Down,
|
|
Released
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
// Allocate button states array
|
|
m_States = new ButtonState[FpsInputButton.count];
|
|
// Add controller disconnect handler (reset button states)
|
|
onIsGamepadConnectedChanged += OnIsGamepadConnectedChanged;
|
|
// Track settings use gamepad property
|
|
FpsSettings.gamepad.onSettingsChanged += OnGamepadSettingsChanged;
|
|
OnGamepadSettingsChanged();
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (!isGamepadConnected || !m_UseGamepad)
|
|
return;
|
|
|
|
// Track axes for current profile
|
|
GamepadProfile p = gamepadProfiles[m_ProfileIndex];
|
|
GamepadUnityInputs g = connectedGamepadInputs;
|
|
|
|
// Check for gamepad connect/disconnect
|
|
s_CastInstance.CheckGamepads();
|
|
|
|
// Updated button states
|
|
for (int i = 0; i < (int)GamepadButton.Count; ++i)
|
|
{
|
|
var gamepadButton = (GamepadButton)i;
|
|
|
|
// Check if button is down
|
|
bool down = g.GetButton(gamepadButton);
|
|
var buttons = p.GetInputButtonsForGamepadButton(gamepadButton);
|
|
|
|
for (int j = 0; j < buttons.Length; ++j)
|
|
{
|
|
var button = buttons[j];
|
|
#if UNITY_EDITOR
|
|
// Error check
|
|
if (button >= m_States.Length)
|
|
{
|
|
Debug.Log("Button out of range: " + (GamepadButton)i);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
// Update state
|
|
switch (m_States[button])
|
|
{
|
|
case ButtonState.Up:
|
|
{
|
|
if (down)
|
|
m_States[button] = ButtonState.Pressed;
|
|
break;
|
|
}
|
|
case ButtonState.Pressed:
|
|
{
|
|
if (down)
|
|
m_States[button] = ButtonState.Down;
|
|
else
|
|
m_States[button] = ButtonState.Released;
|
|
break;
|
|
}
|
|
case ButtonState.Down:
|
|
{
|
|
if (!down)
|
|
m_States[button] = ButtonState.Released;
|
|
break;
|
|
}
|
|
case ButtonState.Released:
|
|
{
|
|
if (!down)
|
|
m_States[button] = ButtonState.Up;
|
|
else
|
|
m_States[button] = ButtonState.Pressed;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public float GetAxis(FpsInputAxis axis)
|
|
{
|
|
if (!isGamepadConnected || !m_UseGamepad)
|
|
return 0f;
|
|
|
|
GamepadProfile p = gamepadProfiles[m_ProfileIndex];
|
|
GamepadUnityInputs g = connectedGamepadInputs;
|
|
|
|
if (p.analogueSetup == GamepadProfile.AnalogueSetup.LeftMoveRightLook)
|
|
{
|
|
switch (axis)
|
|
{
|
|
case FpsInputAxis.MoveX:
|
|
return g.GetLeftAnalogH();
|
|
case FpsInputAxis.MoveY:
|
|
return g.GetLeftAnalogV();
|
|
case FpsInputAxis.LookX:
|
|
return g.GetRightAnalogH();
|
|
case FpsInputAxis.LookY:
|
|
return g.GetRightAnalogV();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (axis)
|
|
{
|
|
case FpsInputAxis.MoveX:
|
|
return g.GetRightAnalogH();
|
|
case FpsInputAxis.MoveY:
|
|
return g.GetRightAnalogV();
|
|
case FpsInputAxis.LookX:
|
|
return g.GetLeftAnalogH();
|
|
case FpsInputAxis.LookY:
|
|
return g.GetLeftAnalogV();
|
|
}
|
|
}
|
|
|
|
return 0f;
|
|
}
|
|
|
|
public float GetAxisRaw(FpsInputAxis axis)
|
|
{
|
|
if (!isGamepadConnected || !m_UseGamepad)
|
|
return 0f;
|
|
|
|
GamepadProfile p = gamepadProfiles[m_ProfileIndex];
|
|
GamepadUnityInputs g = connectedGamepadInputs;
|
|
|
|
if (p.analogueSetup == GamepadProfile.AnalogueSetup.LeftMoveRightLook)
|
|
{
|
|
switch (axis)
|
|
{
|
|
case FpsInputAxis.MoveX:
|
|
return g.GetLeftAnalogRawH();
|
|
case FpsInputAxis.MoveY:
|
|
return g.GetLeftAnalogRawV();
|
|
case FpsInputAxis.LookX:
|
|
return g.GetRightAnalogRawH();
|
|
case FpsInputAxis.LookY:
|
|
return g.GetRightAnalogRawV();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (axis)
|
|
{
|
|
case FpsInputAxis.MoveX:
|
|
return g.GetRightAnalogRawH();
|
|
case FpsInputAxis.MoveY:
|
|
return g.GetRightAnalogRawV();
|
|
case FpsInputAxis.LookX:
|
|
return g.GetLeftAnalogRawH();
|
|
case FpsInputAxis.LookY:
|
|
return g.GetLeftAnalogRawV();
|
|
}
|
|
}
|
|
|
|
return 0f;
|
|
}
|
|
|
|
public bool GetButton(FpsInputButton button)
|
|
{
|
|
if (!m_UseGamepad || !isGamepadConnected)
|
|
return false;
|
|
return m_States[button] == ButtonState.Down || m_States[button] == ButtonState.Pressed;
|
|
}
|
|
|
|
public bool GetButtonDown(FpsInputButton button)
|
|
{
|
|
if (!m_UseGamepad || !isGamepadConnected)
|
|
return false;
|
|
return m_States[button] == ButtonState.Pressed;
|
|
}
|
|
|
|
public bool GetButtonUp(FpsInputButton button)
|
|
{
|
|
if (!m_UseGamepad || !isGamepadConnected)
|
|
return false;
|
|
return m_States[button] == ButtonState.Released;
|
|
}
|
|
|
|
void ResetButtonStates()
|
|
{
|
|
for (int i = 0; i < m_States.Length; ++i)
|
|
m_States[i] = ButtonState.Up;
|
|
}
|
|
|
|
void OnIsGamepadConnectedChanged(bool connected)
|
|
{
|
|
ResetButtonStates();
|
|
}
|
|
|
|
void OnGamepadSettingsChanged()
|
|
{
|
|
bool reset = false;
|
|
// Check if use gamepad has changed
|
|
var useGamepad = FpsSettings.gamepad.useGamepad;
|
|
if (useGamepad != m_UseGamepad)
|
|
{
|
|
m_UseGamepad = useGamepad;
|
|
reset = true;
|
|
}
|
|
// Check if gamepad profile index has changed
|
|
var profile = FpsSettings.gamepad.profile;
|
|
if (profile != m_ProfileIndex)
|
|
{
|
|
m_ProfileIndex = profile;
|
|
reset = true;
|
|
}
|
|
// Reset button states if required
|
|
if (reset)
|
|
ResetButtonStates();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region CODE GENERATION (BUTTONS, AXES, CONTEXTS)
|
|
|
|
#if UNITY_EDITOR
|
|
#pragma warning disable 0414
|
|
|
|
// Script templates
|
|
[SerializeField] private UnityEngine.Object m_ScriptFolder = null;
|
|
[SerializeField] private TextAsset m_ScriptTemplate = null;
|
|
|
|
// Editor foldouts
|
|
[SerializeField] private bool m_ExpandInputButtons = false;
|
|
[SerializeField] private bool m_ExpandInputAxes = false;
|
|
[SerializeField] private bool m_ExpandInputContexts = false;
|
|
|
|
// Copies of the button setup to revert to. Copied from m_InputButtons when the FpsInputButton constants are generated
|
|
[SerializeField] private InputButtonInfo[] m_Revert = { };
|
|
[SerializeField] private InputButtonInfo[] m_Snapshot = { };
|
|
|
|
// Dirty flags for buttons (requires code generation) and button props (display name, default keys, etc)
|
|
[SerializeField] private bool m_ButtonsRequireRebuild = true;
|
|
[SerializeField] private bool m_InputButtonsDirty = true;
|
|
[SerializeField] private int m_InputButtonsError = 0;
|
|
|
|
// Input axes
|
|
[SerializeField] private GeneratorConstantsEntry[] m_InputAxisInfo = null;
|
|
[SerializeField] private bool m_InputAxisDirty = false;
|
|
[SerializeField] private int m_InputAxisError = 1;
|
|
|
|
public override bool showError
|
|
{
|
|
get { return base.showError || m_InputAxisError > 0 || m_InputButtonsError > 0; }
|
|
}
|
|
|
|
#pragma warning restore 0414
|
|
#endif
|
|
|
|
#endregion
|
|
}
|
|
}
|