Working on it

This commit is contained in:
2020-04-18 18:14:51 +10:00
commit a3b19da551
236 changed files with 16300 additions and 0 deletions

View File

@@ -0,0 +1,268 @@
using UnityEngine;
// Users don't have to use this directly, so there is no need to have this in global namespace
namespace CarbonInput {
/// <summary>
/// Describes a mapping for a specific controller. This mapping is independend of the PlayerIndex.
/// Each CarbonController defines how buttons and axes are mapped correctly to the Unity Input.
/// </summary>
[CreateAssetMenu(fileName = "NewCarbonMapping", menuName = "Carbon Input/GamePad Mapping")]
public class CarbonController : ScriptableObject {
/// <summary>
/// Number of buttons defined in the <see cref="CButton"/> enumeration.
/// </summary>
public const int ButtonCount = 10; // Must match the CButton enum!
/// <summary>
/// Number of axes defined in the <see cref="AxisCount"/> enumeration.
/// </summary>
public const int AxisCount = 8; // Must match the CAxis enum!
/// <summary>
/// Number of generated axes,
/// </summary>
public const int InputAxisCount = 16; // Must match the number of generated Input axes!
/// <summary>
/// Number of joystick buttons supported by unity.
/// </summary>
public const int JoystickButtonCount = 20; // Number of joystick buttons supported by Unity
/// <summary>
/// Number of entries in <see cref="PlayerIndex"/> enumeration.
/// </summary>
public const int PlayerIndices = 9; // Any, One, ..., Eight
/// <summary>
/// Prefix of all generated axes.
/// </summary>
public const string Tag = "cin_Axis";
/// <summary>
/// Mapping of [<see cref="PlayerIndex"/>, JoystickAxis] to its name.
/// </summary>
private static readonly string[,] AxisNames;
static CarbonController() {
// construct all strings beforehand
AxisNames = new string[PlayerIndices, InputAxisCount];
for(int id = 0; id < PlayerIndices; id++) {
for(int axis = 0; axis < InputAxisCount; axis++) {
AxisNames[id, axis] = CreateName(id, axis);
}
}
}
/// <summary>
/// Create the input axis name for <see cref="PlayerIndex"/> and axis.
/// </summary>
/// <param name="id"></param>
/// <param name="axis"></param>
/// <returns></returns>
public static string CreateName(int id, int axis) {
return Tag + id + "_" + axis.ToString("D2");
}
/// <summary>
/// Regular expression used to check if this mapping can be used for a controller.
/// </summary>
public string RegEx;
/// <summary>
/// Platforms supported by this mapping.
/// </summary>
public CPlatform Platform;
/// <summary>
/// Priority of this mapping. On startup the system will try to find a correct mapping for all controller. Lower priority mappings will be tester earlier.
/// </summary>
public int Priority = 1000;
/// <summary>
/// If true, this mapping will only be used once, even if it could be used multiple times.
/// </summary>
public bool UseOnce;
/// <summary>
/// If true, this mapping can be replaced by touch mappings.
/// </summary>
public bool Replacable;
/// <summary>
/// All mappings for all possible <see cref="CAxis"/>. This array must have exactly <see cref="AxisCount"/> many entries.
/// </summary>
public AxisMapping[] Axes = new AxisMapping[AxisCount];
/// <summary>
/// All mappings for all possible <see cref="CButton"/>s. This array must have exactly <see cref="ButtonCount"/> many entries.
/// </summary>
public ButtonMapping[] Buttons = new ButtonMapping[ButtonCount];
/// <summary>
/// Returns true if this mapping is a fallback mapping.
/// A mapping is considered a fallback, if it doesn't have a proper <see cref="RegEx"/>.
/// By default, the keyboard is considered a fallback mapping.
/// </summary>
/// <returns></returns>
public bool IsFallback() {
return string.IsNullOrEmpty(RegEx);
}
public CarbonController() {
for(int i = 0; i < Buttons.Length; i++) Buttons[i] = new ButtonMapping();
for(int i = 0; i < Axes.Length; i++) Axes[i] = new AxisMapping();
}
/// <summary>
/// Checks if controller button btn of player id is pressed.
/// </summary>
/// <param name="btn">GamePad button</param>
/// <param name="id">Index of player</param>
/// <returns></returns>
public virtual bool GetButton(CButton btn, int id) {
ButtonMapping key = Buttons[(int)btn];
if(key.Type == ButtonMapping.ButtonType.Wrapper) {
if(key.Key != KeyCode.None) return Input.GetKey(key.Key);
} else {
//JoystickButton0 = 330 ... JoystickButton19 = 349
//Joystick1Button0 = 350 ... Joystick1Button19 = 369
// ...
//Joystick8Button0 = 490 ... Joystick8Button19 = 509
return Input.GetKey(KeyCode.JoystickButton0 + id * JoystickButtonCount + key.Button);
}
return false;
}
/// <summary>
/// Returns the value of the virtual axis of player <paramref name="id"/> identified by the <paramref name="axis"/> parameter;
/// </summary>
/// <param name="axis"></param>
/// <param name="id"></param>
/// <returns></returns>
public virtual float GetAxis(CAxis axis, int id) {
AxisMapping mapping = Axes[(int)axis];
float result = 0;
switch(mapping.Type) {
case AxisMapping.AxisType.Default:
result = Input.GetAxis(AxisNames[id, mapping.Axis]);
break;
case AxisMapping.AxisType.ButtonWrapper:
result = Input.GetKey(KeyCode.JoystickButton0 + id * JoystickButtonCount + mapping.Axis) ? mapping.Max : mapping.Min;
break;
case AxisMapping.AxisType.KeyWrapper:
bool key1 = Input.GetKey(mapping.Key1);
bool key2 = Input.GetKey(mapping.Key2);
if(key1 && !key2) result = -1;
else if(!key1 && key2) result = 1;
else result = 0;
break;
case AxisMapping.AxisType.Clamped:
result = Mathf.Clamp(Input.GetAxis(AxisNames[id, mapping.Axis]), mapping.Min, mapping.Max);
break;
case AxisMapping.AxisType.ButtonWrapper2:
key1 = Input.GetKey(KeyCode.JoystickButton0 + id * JoystickButtonCount + mapping.Axis);
key2 = Input.GetKey(KeyCode.JoystickButton0 + id * JoystickButtonCount + mapping.Alternative);
if(key1 && !key2) result = -1;
else if(!key1 && key2) result = 1;
else result = 0;
break;
case AxisMapping.AxisType.TriggerLimiter:
result = (Input.GetAxis(AxisNames[id, mapping.Axis]) + 1f) / 2f;
break;
}
if(mapping.Invert) return -result;
return result;
}
/// <summary>
/// Returns true if this mapping is supported on the execution platform.
/// </summary>
/// <returns></returns>
public bool SupportedOnThisPlatform() {
switch(Application.platform) {
case RuntimePlatform.WebGLPlayer: return Has(CPlatform.WebGL);
case RuntimePlatform.Android: return Has(CPlatform.Android);
case RuntimePlatform.IPhonePlayer: return Has(CPlatform.IOS);
case RuntimePlatform.LinuxEditor:
case RuntimePlatform.LinuxPlayer: return Has(CPlatform.Linux);
case RuntimePlatform.OSXEditor:
case RuntimePlatform.OSXPlayer:
return Has(CPlatform.OSX);
case RuntimePlatform.PS4: return Has(CPlatform.PS4);
#if !UNITY_2018_3_OR_NEWER
case RuntimePlatform.PSP2: return Has(CPlatform.PSP2);
#endif
#if !UNITY_2018_1_OR_NEWER
case RuntimePlatform.WiiU: return Has(CPlatform.Wii);
#endif
case RuntimePlatform.WindowsEditor:
case RuntimePlatform.WindowsPlayer: return Has(CPlatform.Windows);
case RuntimePlatform.WSAPlayerARM:
case RuntimePlatform.WSAPlayerX64:
case RuntimePlatform.WSAPlayerX86: return Has(CPlatform.WSA);
case RuntimePlatform.XboxOne: return Has(CPlatform.XBoxOne);
}
return false;
}
/// <summary>
/// Checks if the given <see cref="CPlatform"/> is set in <see cref="Platform"/>.
/// </summary>
/// <param name="flag"></param>
/// <returns></returns>
private bool Has(CPlatform flag) {
return (Platform & flag) == flag;
}
/// <summary>
/// This will return a fallback instance, using the keyboard.
/// </summary>
/// <returns></returns>
public static CarbonController CreateFallback() {
CarbonController cc = CreateInstance<CarbonController>();
cc.Platform = (CPlatform)(-1);
MakeKeyWrapper(cc.Buttons[0], KeyCode.RightShift);
MakeKeyWrapper(cc.Buttons[1], KeyCode.RightControl);
MakeKeyWrapper(cc.Buttons[2], KeyCode.LeftShift);
MakeKeyWrapper(cc.Buttons[3], KeyCode.Space);
MakeKeyWrapper(cc.Buttons[4], KeyCode.Escape);
MakeKeyWrapper(cc.Buttons[5], KeyCode.Return);
MakeKeyWrapper(cc.Buttons[6], KeyCode.Q);
MakeKeyWrapper(cc.Buttons[7], KeyCode.E);
MakeKeyWrapper(cc.Buttons[8]);
MakeKeyWrapper(cc.Buttons[9]);
MakeKeyWrapper(cc.Axes[0], KeyCode.A, KeyCode.D);
MakeKeyWrapper(cc.Axes[1], KeyCode.W, KeyCode.S);
for(int i = 2; i < AxisCount; i++) MakeKeyWrapper(cc.Axes[i]);
return cc;
}
/// <summary>
/// This will return a fallback instance, which doesn't respond to any key.
/// </summary>
/// <returns></returns>
public static CarbonController CreateDisabledInput() {
var cc = CreateInstance<CarbonController>();
cc.name = "DisabledInput";
cc.Platform = (CPlatform)(-1);
cc.Replacable = true;
for(int i = 0; i < ButtonCount; i++)
MakeKeyWrapper(cc.Buttons[i]);
for(int i = 0; i < AxisCount; i++)
MakeKeyWrapper(cc.Axes[i]);
return cc;
}
/// <summary>
/// Sets the given <see cref="AxisMapping"/> to be a <see cref="AxisMapping.AxisType.KeyWrapper"/>
/// </summary>
/// <param name="mapping"></param>
/// <param name="key1"></param>
/// <param name="key2"></param>
private static void MakeKeyWrapper(AxisMapping mapping, KeyCode key1 = KeyCode.None, KeyCode key2 = KeyCode.None) {
mapping.Type = AxisMapping.AxisType.KeyWrapper;
mapping.Key1 = key1;
mapping.Min = key1 != KeyCode.None ? -1 : 0;
mapping.Key2 = key2;
mapping.Max = key2 != KeyCode.None ? 1 : 0;
}
/// <summary>
/// Sets the given <see cref="ButtonMapping"/> to be a <see cref="ButtonMapping.ButtonType.Wrapper"/>.
/// </summary>
/// <param name="mapping"></param>
/// <param name="key"></param>
private static void MakeKeyWrapper(ButtonMapping mapping, KeyCode key = KeyCode.None) {
mapping.Type = ButtonMapping.ButtonType.Wrapper;
mapping.Key = key;
}
}
}