using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using CarbonInput;
///
/// Interface to the carbon controller input system.
///
// ReSharper disable once CheckNamespace
// ReSharper disable InconsistentNaming
public static class GamePad {
public delegate void OnReloadEvent();
///
/// This event is fired when a reload has happened.
///
public static event OnReloadEvent OnReload;
///
/// Used for lazy initialization.
///
private static bool IsInitialized;
///
/// Array of all mappings supporting this platform.
///
private static CarbonController[] AllMappings;
///
/// One mapping for each player, including (index 0).
///
private static ControllerInstance[] PlayerMappings;
///
/// s of all players.
///
private static readonly GamePadState[] States = new GamePadState[CarbonController.PlayerIndices];
///
/// Number of connected and supported hardware gamepads, without TouchInput/Keyboard.
///
private static int gamepadCount;
///
/// Number of connected and supported hardware gamepads, without TouchInput/Keyboard.
///
public static int GamePadCount { get { if(!IsInitialized) Initialize(); return gamepadCount; } }
///
/// Used to store settings like and inverted axes.
///
private static CarbonSettings settings;
///
/// Used to store settings like and inverted axes.
///
public static CarbonSettings Settings {
get {
if(!IsInitialized) Initialize();
return settings;
}
set {
if(!IsInitialized) Initialize();
settings = value;
}
}
private static readonly CarbonController disabledInput = CarbonController.CreateDisabledInput();
///
/// Returns an array of all mappings supported by this platform.
///
///
public static CarbonController[] GetAllMappings() {
if(!IsInitialized) Initialize();
return AllMappings;
}
///
/// Returns an array of all player mappings. Index 0 is the mapping for and indices 1 to 8 meant to
/// reference to .
///
///
public static ControllerInstance[] GetPlayerMappings() {
if(!IsInitialized) Initialize();
return PlayerMappings;
}
///
/// Reinitializes all GamePads.
///
public static void ReInit() {
var touchMappings = GetPlayerMappings().Skip(1).Where(x => x.Controller is TouchMapping).ToList();
Initialize();
var mappings = GetPlayerMappings();
int idx = 0;
for(int i = 1; i < CarbonController.PlayerIndices && idx < touchMappings.Count; i++) {
if(mappings[i] != null && mappings[i].Controller.Replacable) {
mappings[i] = touchMappings[idx++];
if(i == 1) mappings[0] = mappings[1]; // required for PlayerIndex.Any if used with AnyBehaviour.UseMappingOne
}
}
if(OnReload != null)
OnReload();
}
///
/// Initializes this library by loading all mappings from file and matching the given gamepads.
///
private static void Initialize() {
if(!IsInitialized) { // first init
new GameObject("GamePad ReInit").AddComponent();
}
List mappings = new List(Resources.LoadAll("Mappings")); // load all mappings
mappings.RemoveAll(mapping => !mapping.SupportedOnThisPlatform()); // keep only mappings for this platform
mappings.Sort((a, b) => a.Priority - b.Priority); // sort by priority, lower is better
AllMappings = mappings.ToArray();
// now try to match with the names of the connected joysticks
int nameIndex = 0;
gamepadCount = 0;
List matches = new List();
foreach(string name in Input.GetJoystickNames()) {
CarbonController toRemove = null;
foreach(CarbonController cc in mappings) {
if(!string.IsNullOrEmpty(cc.RegEx) && Regex.IsMatch(name, cc.RegEx, RegexOptions.IgnoreCase)) {
matches.Add(new ControllerInstance(cc, nameIndex));
gamepadCount++;
if(cc.UseOnce) toRemove = cc;
break;
}
}
if(toRemove != null) mappings.Remove(toRemove);
nameIndex++;
}
// add fallbacks (keyboard)
var fallbacks = AllMappings.Where(x => x.IsFallback()).ToList();
fallbacks.Add(disabledInput);
PlayerMappings = new ControllerInstance[CarbonController.PlayerIndices];
for(int i = 1; i < CarbonController.PlayerIndices; i++) {
int idx = i - 1;
if(idx < matches.Count) PlayerMappings[i] = matches[idx]; // real GamePad
else { // Keyboard Fallback
var fallback = fallbacks.First();
PlayerMappings[i] = new ControllerInstance(fallback, idx);
if(fallback.UseOnce) fallbacks.RemoveAt(0);
}
}
PlayerMappings[0] = PlayerMappings[1]; // always use first found mapping as the "global" mapping for Anyone
for(int i = 0; i < CarbonController.PlayerIndices; i++) States[i] = new GamePadState((PlayerIndex)i);
settings = CarbonSettings.Default();
IsInitialized = true;
}
///
/// Returns the mapping used by player .
///
///
///
public static ControllerInstance GetMapping(PlayerIndex id) {
if(!IsInitialized) Initialize();
return PlayerMappings[(int)id];
}
///
/// Returns true if there is any real gamepad connected.
///
///
public static bool AnyConnected() {
if(!IsInitialized) Initialize();
return gamepadCount > 0;
}
///
/// Returns the state of button of player .
///
///
///
///
public static bool GetButton(CButton btn, PlayerIndex id = PlayerIndex.Any) {
if(!IsInitialized) Initialize();
if(id == PlayerIndex.Any) {
switch(settings.Behaviour) {
case AnyBehaviour.UseControllerOne: return PlayerMappings[1].GetButton(btn);
case AnyBehaviour.CheckAll:
for(int i = 1; i < CarbonController.PlayerIndices; i++) {
if(PlayerMappings[i].GetButton(btn)) return true;
}
return false;
}
}
return PlayerMappings[(int)id].GetButton(btn);
}
///
/// Returns the state of button of player using a playstation controller layout.
///
///
///
///
public static bool GetButton(PSButton btn, PlayerIndex id = PlayerIndex.Any) {
return GetButton((CButton)btn, id);
}
///
/// Returns the of player . The result is in range [-1, 1], except for the two triggers.
/// They are in range [0, 1].
///
///
///
///
public static float GetAxis(CAxis axis, PlayerIndex id = PlayerIndex.Any) {
if(!IsInitialized) Initialize();
if(Settings[axis]) return -GetAxisRaw(axis, id);
return GetAxisRaw(axis, id);
}
private static float GetAxisRaw(CAxis axis, PlayerIndex id) {
if(id == PlayerIndex.Any) {
switch(settings.Behaviour) {
case AnyBehaviour.UseControllerOne: return PlayerMappings[1].GetAxis(axis);
case AnyBehaviour.CheckAll:
for(int i = 1; i < CarbonController.PlayerIndices; i++) {
float value = PlayerMappings[i].GetAxis(axis);
if(Mathf.Abs(value) > 0.02f) return value;
}
return 0f;
}
}
return PlayerMappings[(int)id].GetAxis(axis);
}
///
/// Returns a for the specified stick of player .
///
///
///
///
public static Vector2 GetStick(CStick stick, PlayerIndex id = PlayerIndex.Any) {
switch(stick) {
case CStick.Left: return GetLeftStick(id);
case CStick.Right: return GetRightStick(id);
default: return GetDPad(id);
}
}
///
/// Returns a vector for the left thumbstick of player .
///
///
///
public static Vector2 GetLeftStick(PlayerIndex id = PlayerIndex.Any) {
return new Vector2(GetAxis(CAxis.LX, id), GetAxis(CAxis.LY, id));
}
///
/// Returns a vector for the right thumbstick of player .
///
///
///
public static Vector2 GetRightStick(PlayerIndex id = PlayerIndex.Any) {
return new Vector2(GetAxis(CAxis.RX, id), GetAxis(CAxis.RY, id));
}
///
/// Returns the left trigger of player . Result is in range [0, 1].
///
///
///
public static float GetLeftTrigger(PlayerIndex id = PlayerIndex.Any) {
return GetAxis(CAxis.LT, id);
}
///
/// Returns the right trigger of player . Result is in range [0, 1].
///
///
///
public static float GetRightTrigger(PlayerIndex id = PlayerIndex.Any) {
return GetAxis(CAxis.RT, id);
}
///
/// Returns a vector for the dpad of player .
///
///
///
public static Vector2 GetDPad(PlayerIndex id = PlayerIndex.Any) {
return new Vector2(GetAxis(CAxis.DX, id), GetAxis(CAxis.DY, id));
}
///
/// Returns the state of player .
/// A contains all pressed buttons and axes values.
/// It also stores information from the last frame in order to distinguish between a single press and a continuous pressing.
///
///
///
public static GamePadState GetState(PlayerIndex id = PlayerIndex.Any) {
if(!IsInitialized) Initialize();
GamePadState state = States[(int)id];
state.Update();
return state;
}
}