├── InputManager.asset ├── OuyaInput.unitypackage ├── README.md ├── ControllerDocumentation.pdf ├── OuyaInputTester.cs ├── InputHandlerPattern.cs ├── InputHandlerPattern.js └── OuyaInput.cs /InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitbutter/OuyaInputFramework/master/InputManager.asset -------------------------------------------------------------------------------- /OuyaInput.unitypackage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitbutter/OuyaInputFramework/master/OuyaInput.unitypackage -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OuyaInputFramework 2 | ================== 3 | 4 | Cross-platform controller support for OUYA and Unity 5 | -------------------------------------------------------------------------------- /ControllerDocumentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitbutter/OuyaInputFramework/master/ControllerDocumentation.pdf -------------------------------------------------------------------------------- /OuyaInputTester.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class OuyaInputTester : MonoBehaviour 5 | { 6 | // attach this script to any GameObject 7 | // this tester script draws a GUI overlay to display controller values 8 | // trigger and d-pad button events are displayed via the debug console 9 | // as Unity's basic GUI is slow and we do create a lot of strings here 10 | // performance and garbage collection might by bad – this has nothing to do with OuyaInput 11 | // please note that any lag in the console messages is due to the slow debug console 12 | // OuyaInput should have very low latency and nearly no garbage collection 13 | 14 | /* INSPECTOR */ 15 | // easy switch to stop the GUI overlay 16 | public bool debug = true; 17 | 18 | // do we want to scan for trigger and d-pad button events ? 19 | public bool continiousScan = true; 20 | 21 | // the player we want to observe 22 | public OuyaPlayer observedPlayer = OuyaPlayer.P01; 23 | 24 | // the platform we are working on (installation editor) 25 | public EditorWorkPlatform editorWorkPlatform = EditorWorkPlatform.MacOS; 26 | 27 | // the type of deadzone we want to use for convenience access 28 | public DeadzoneType deadzoneType = DeadzoneType.CircularMap; 29 | 30 | // the size of the deadzone 31 | public float deadzone = 0.25f; 32 | public float triggerTreshold = 0.1f; 33 | 34 | 35 | /* ----------------------------------------------------------------------------------- 36 | * INITIAL SETUP 37 | */ 38 | 39 | public void Start() 40 | { 41 | // set the editor platform to get correct input while testing in the editor 42 | OuyaInput.SetEditorPlatform(editorWorkPlatform); 43 | 44 | // set button state scanning to receive input state events for trigger and d-pads 45 | OuyaInput.SetContiniousScanning(continiousScan); 46 | 47 | // define the deadzone if you want to use advanced joystick and trigger access 48 | OuyaInput.SetDeadzone(deadzoneType, deadzone); 49 | OuyaInput.SetTriggerTreshold(triggerTreshold); 50 | 51 | // do one controller update here to get everything started as soon as possible 52 | OuyaInput.UpdateControllers(); 53 | } 54 | 55 | /* ----------------------------------------------------------------------------------- 56 | * GUI CONTROLLER DISPLAY 57 | */ 58 | 59 | public void OnGUI() 60 | { 61 | if (debug) 62 | { 63 | GUI.Label(new Rect(50, 40, 100, 20), "LX " + OuyaInput.GetAxis(OuyaAxis.LX, observedPlayer)); 64 | GUI.Label(new Rect(50, 60, 100, 20), "LY " + OuyaInput.GetAxis(OuyaAxis.LY, observedPlayer)); 65 | 66 | GUI.Label(new Rect(250, 40, 100, 20), "RX " + OuyaInput.GetAxis(OuyaAxis.RX, observedPlayer)); 67 | GUI.Label(new Rect(250, 60, 100, 20), "RY " + OuyaInput.GetAxis(OuyaAxis.RY, observedPlayer)); 68 | 69 | GUI.Label(new Rect(50, 100, 200, 20), "LT " + OuyaInput.GetAxis(OuyaAxis.LT, observedPlayer)); 70 | GUI.Label(new Rect(50, 120, 200, 20), "RT " + OuyaInput.GetAxis(OuyaAxis.RT, observedPlayer)); 71 | 72 | GUI.Label(new Rect(250, 100, 200, 20), "LT-B " + OuyaInput.GetButton(OuyaButton.LT, observedPlayer)); 73 | GUI.Label(new Rect(250, 120, 200, 20), "RT-B " + OuyaInput.GetButton(OuyaButton.RT, observedPlayer)); 74 | 75 | GUI.Label(new Rect(50, 160, 100, 20), "DX " + OuyaInput.GetAxis(OuyaAxis.DX, observedPlayer)); 76 | GUI.Label(new Rect(50, 180, 100, 20), "DY " + OuyaInput.GetAxis(OuyaAxis.DY, observedPlayer)); 77 | 78 | GUI.Label(new Rect(50, 200, 100, 20), "L3 " + OuyaInput.GetButton(OuyaButton.L3, observedPlayer)); 79 | GUI.Label(new Rect(50, 220, 100, 20), "R3 " + OuyaInput.GetButton(OuyaButton.R3, observedPlayer)); 80 | 81 | GUI.Label(new Rect(250, 160, 100, 20), "DU-B " + OuyaInput.GetButton(OuyaButton.DU, observedPlayer)); 82 | GUI.Label(new Rect(250, 180, 100, 20), "DD-B " + OuyaInput.GetButton(OuyaButton.DD, observedPlayer)); 83 | GUI.Label(new Rect(250, 200, 100, 20), "DL-B " + OuyaInput.GetButton(OuyaButton.DL, observedPlayer)); 84 | GUI.Label(new Rect(250, 220, 100, 20), "DR-B " + OuyaInput.GetButton(OuyaButton.DR, observedPlayer)); 85 | 86 | GUI.Label(new Rect(250, 260, 200, 20), "LB " + OuyaInput.GetButton(OuyaButton.LB, observedPlayer)); 87 | GUI.Label(new Rect(250, 280, 200, 20), "RB " + OuyaInput.GetButton(OuyaButton.RB, observedPlayer)); 88 | 89 | GUI.Label(new Rect(50, 260, 100, 20), "O " + OuyaInput.GetButton(OuyaButton.O, observedPlayer)); 90 | GUI.Label(new Rect(50, 280, 100, 20), "U " + OuyaInput.GetButton(OuyaButton.U, observedPlayer)); 91 | GUI.Label(new Rect(50, 300, 100, 20), "Y " + OuyaInput.GetButton(OuyaButton.Y, observedPlayer)); 92 | GUI.Label(new Rect(50, 320, 100, 20), "A " + OuyaInput.GetButton(OuyaButton.A, observedPlayer)); 93 | 94 | GUI.Label(new Rect(50, 360, 100, 20), "SEL " + OuyaInput.GetButton(OuyaButton.SELECT, observedPlayer)); 95 | GUI.Label(new Rect(50, 380, 100, 20), "SYS " + OuyaInput.GetButton(OuyaButton.SYSTEM, observedPlayer)); 96 | GUI.Label(new Rect(50, 400, 100, 20), "START " + OuyaInput.GetButton(OuyaButton.START, observedPlayer)); 97 | 98 | GUI.Label(new Rect(50, 440, 600, 20), "JOY_L " + OuyaInput.GetJoystick(OuyaJoystick.LeftStick, observedPlayer)); 99 | GUI.Label(new Rect(50, 460, 600, 20), "JOY_R " + OuyaInput.GetJoystick(OuyaJoystick.RightStick, observedPlayer)); 100 | GUI.Label(new Rect(50, 480, 600, 20), "JOY_D " + OuyaInput.GetJoystick(OuyaJoystick.DPad, observedPlayer)); 101 | 102 | GUI.Label(new Rect(50, 520, 600, 20), "NAME " + OuyaInput.GetControllerName(observedPlayer)); 103 | GUI.Label(new Rect(50, 540, 600, 20), "TYPE " + OuyaInput.GetControllerType(observedPlayer)); 104 | } 105 | } 106 | 107 | /* ----------------------------------------------------------------------------------- 108 | * GUI CONTROLLER DISPLAY 109 | */ 110 | 111 | public void Update() 112 | { 113 | if (debug) 114 | { 115 | /* UPDATE CONTROLERS */ 116 | // IMPORTANT! update the controllers here for best results 117 | OuyaInput.UpdateControllers(); 118 | 119 | /* CONSOLE TRIGGER AND D-PAD EVENTS */ 120 | if (OuyaInput.GetButtonDown(OuyaButton.LT, observedPlayer)) Debug.Log("LT down event"); 121 | if (OuyaInput.GetButtonUp(OuyaButton.LT, observedPlayer)) Debug.Log("LT up event"); 122 | if (OuyaInput.GetButtonDown(OuyaButton.RT, observedPlayer)) Debug.Log("RT down event"); 123 | if (OuyaInput.GetButtonUp(OuyaButton.RT, observedPlayer)) Debug.Log("RT up event"); 124 | if (OuyaInput.GetButtonUp(OuyaButton.DU, observedPlayer)) Debug.Log("DU up event"); 125 | if (OuyaInput.GetButtonDown(OuyaButton.DU, observedPlayer)) Debug.Log("DU down event"); 126 | if (OuyaInput.GetButtonUp(OuyaButton.DD, observedPlayer)) Debug.Log("DD up event"); 127 | if (OuyaInput.GetButtonDown(OuyaButton.DD, observedPlayer)) Debug.Log("DD down event"); 128 | if (OuyaInput.GetButtonUp(OuyaButton.DR, observedPlayer)) Debug.Log("DR up event"); 129 | if (OuyaInput.GetButtonDown(OuyaButton.DR, observedPlayer)) Debug.Log("DR down event"); 130 | if (OuyaInput.GetButtonUp(OuyaButton.DL, observedPlayer)) Debug.Log("DL up event"); 131 | if (OuyaInput.GetButtonDown(OuyaButton.DL, observedPlayer)) Debug.Log("DL down event"); 132 | } 133 | } 134 | } 135 | 136 | -------------------------------------------------------------------------------- /InputHandlerPattern.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class InputHandlerPattern : MonoBehaviour 5 | { 6 | // attach this script to any GameObject 7 | // in most cases this sits on the object that should be controlled via input 8 | // this pattern example shows how to get every input from a players controller 9 | // there is no GUI showing the results as I wanted to make this simple, reusable and clean 10 | 11 | /* INSPECTOR */ 12 | 13 | // do we want to scan for trigger and d-pad button events ? 14 | public bool continuousScan = true; 15 | 16 | // the player we want to get input for 17 | public OuyaPlayer player = OuyaPlayer.P01; 18 | 19 | // the platform we are working on (installation editor) 20 | public EditorWorkPlatform editorWorkPlatform = EditorWorkPlatform.MacOS; 21 | 22 | // the type of deadzone we want to use for convenience access 23 | public DeadzoneType deadzoneType = DeadzoneType.CircularClip; 24 | 25 | // the size of the deadzone 26 | public float deadzone = 0.25f; 27 | public float triggerTreshold = 0.2f; 28 | 29 | 30 | /* ----------------------------------------------------------------------------------- 31 | * INITIAL SETUP 32 | */ 33 | 34 | public void Start() 35 | { 36 | // set the editor platform to get correct input while testing in the editor 37 | OuyaInput.SetEditorPlatform(editorWorkPlatform); 38 | 39 | // OPTIONAL: set button state scanning to receive input state events for trigger and d-pads 40 | OuyaInput.SetContinuousScanning(continuousScan); 41 | 42 | // OPTIONAL: define the deadzone if you want to use advanced joystick and trigger access 43 | OuyaInput.SetDeadzone(deadzoneType, deadzone); 44 | OuyaInput.SetTriggerTreshold(triggerTreshold); 45 | 46 | // do one controller update here to get everything started as soon as possible 47 | OuyaInput.UpdateControllers(); 48 | } 49 | 50 | 51 | /* ----------------------------------------------------------------------------------- 52 | * UPDATE CYCLE 53 | */ 54 | 55 | public void Update() 56 | { 57 | /* UPDATE CONTROLERS */ 58 | // IMPORTANT! update the controllers here for best results 59 | OuyaInput.UpdateControllers(); 60 | 61 | /* GET VALUES FOR CONTROLLER AXES */ 62 | 63 | // left joystick 64 | float x_Axis_LeftStick = OuyaInput.GetAxis(OuyaAxis.LX, player); 65 | float y_Axis_LeftStick = OuyaInput.GetAxis(OuyaAxis.LY, player); 66 | 67 | // right joystick 68 | float x_Axis_RightStick = OuyaInput.GetAxis(OuyaAxis.RX, player); 69 | float y_Axis_RightStick = OuyaInput.GetAxis(OuyaAxis.RY, player); 70 | 71 | // d-pad 72 | float x_Axis_DPad = OuyaInput.GetAxis(OuyaAxis.DX, player); 73 | float y_Axis_DPad = OuyaInput.GetAxis(OuyaAxis.DY, player); 74 | 75 | // triggers 76 | float axis_LeftTrigger = OuyaInput.GetAxis(OuyaAxis.LT, player); 77 | float axis_RightTrigger = OuyaInput.GetAxis(OuyaAxis.RT, player); 78 | 79 | // examples for deadzone clipping (we can choose between three types) 80 | Vector2 leftStickInput = OuyaInput.CheckDeadzoneCircular(x_Axis_LeftStick, y_Axis_LeftStick, deadzone); 81 | Vector2 rightStickInput = OuyaInput.CheckDeadzoneRescaled(x_Axis_RightStick, y_Axis_RightStick, deadzone); 82 | Vector2 dPadInput = OuyaInput.CheckDeadzoneRescaled(x_Axis_DPad, y_Axis_DPad, deadzone); 83 | 84 | /* GET ADVANCED JOYSTICK AND TRIGGER INPUT WITH DEADZONE MAPPING */ 85 | 86 | // examples for easy (or precision) joystick input 87 | Vector2 leftJoystick = OuyaInput.GetJoystick(OuyaJoystick.LeftStick, player); 88 | Vector2 rightJoystick = OuyaInput.GetJoystick(OuyaJoystick.RightStick, player); 89 | Vector2 dPad = OuyaInput.GetJoystick(OuyaJoystick.DPad, player); 90 | 91 | // examples for easy (or precision) trigger input 92 | float leftTrigger = OuyaInput.GetTrigger(OuyaTrigger.Left, player); 93 | float rightTrigger = OuyaInput.GetTrigger(OuyaTrigger.Right, player); 94 | 95 | /* GET PRESSED STATES FOR CONTROLLER BUTTONS */ 96 | 97 | // O U Y A buttons 98 | bool pressed_O = OuyaInput.GetButton(OuyaButton.O, player); 99 | bool pressed_U = OuyaInput.GetButton(OuyaButton.U, player); 100 | bool pressed_Y = OuyaInput.GetButton(OuyaButton.Y, player); 101 | bool pressed_A = OuyaInput.GetButton(OuyaButton.A, player); 102 | 103 | // joystick click down buttons 104 | bool pressed_LeftStick = OuyaInput.GetButton(OuyaButton.L3, player); 105 | bool pressed_RightStick = OuyaInput.GetButton(OuyaButton.R3, player); 106 | 107 | // trigger buttons 108 | bool pressed_LeftTrigger = OuyaInput.GetButton(OuyaButton.LT, player); 109 | bool pressed_RightTrigger = OuyaInput.GetButton(OuyaButton.RT, player); 110 | 111 | // center buttons 112 | bool pressed_Start = OuyaInput.GetButton(OuyaButton.START, player); 113 | bool pressed_Select = OuyaInput.GetButton(OuyaButton.SELECT, player); 114 | bool pressed_System = OuyaInput.GetButton(OuyaButton.SYSTEM, player); 115 | 116 | /* GET DOWN EVENTS FOR CONTROLLER BUTTONS */ 117 | 118 | // we need to have OuyaInput.SetContinuousScanning(true) in Start() 119 | // some controllers might work without this but we want to make sure 120 | if (continuousScan) 121 | { 122 | // O U Y A buttons 123 | bool down_O = OuyaInput.GetButtonDown(OuyaButton.O, player); 124 | bool down_U = OuyaInput.GetButtonDown(OuyaButton.U, player); 125 | bool down_Y = OuyaInput.GetButtonDown(OuyaButton.Y, player); 126 | bool down_A = OuyaInput.GetButtonDown(OuyaButton.A, player); 127 | 128 | // joystick click down buttons 129 | bool down_LeftStick = OuyaInput.GetButtonDown(OuyaButton.L3, player); 130 | bool down_RightStick = OuyaInput.GetButtonDown(OuyaButton.R3, player); 131 | 132 | // trigger buttons 133 | bool down_LeftTrigger = OuyaInput.GetButtonDown(OuyaButton.LT, player); 134 | bool down_RightTrigger = OuyaInput.GetButtonDown(OuyaButton.RT, player); 135 | 136 | // center buttons 137 | bool down_Start = OuyaInput.GetButtonDown(OuyaButton.START, player); 138 | bool down_Select = OuyaInput.GetButtonDown(OuyaButton.SELECT, player); 139 | bool down_System = OuyaInput.GetButtonDown(OuyaButton.SYSTEM, player); 140 | } 141 | 142 | /* GET UP (RELEASE) EVENTS FOR CONTROLLER BUTTONS */ 143 | 144 | // we need to have OuyaInput.SetContinuousScanning(true) in Start() 145 | // some controllers might work without this but we want to make sure 146 | if (continuousScan) 147 | { 148 | // O U Y A buttons 149 | bool up_O = OuyaInput.GetButtonUp(OuyaButton.O, player); 150 | bool up_U = OuyaInput.GetButtonUp(OuyaButton.U, player); 151 | bool up_Y = OuyaInput.GetButtonUp(OuyaButton.Y, player); 152 | bool up_A = OuyaInput.GetButtonUp(OuyaButton.A, player); 153 | 154 | // joystick click down buttons 155 | bool up_LeftStick = OuyaInput.GetButtonUp(OuyaButton.L3, player); 156 | bool up_RightStick = OuyaInput.GetButtonUp(OuyaButton.R3, player); 157 | 158 | // trigger buttons 159 | bool up_LeftTrigger = OuyaInput.GetButtonUp(OuyaButton.LT, player); 160 | bool up_RightTrigger = OuyaInput.GetButtonUp(OuyaButton.RT, player); 161 | 162 | // center buttons 163 | bool up_Start = OuyaInput.GetButtonUp(OuyaButton.START, player); 164 | bool up_Select = OuyaInput.GetButtonUp(OuyaButton.SELECT, player); 165 | bool up_System = OuyaInput.GetButtonUp(OuyaButton.SYSTEM, player); 166 | } 167 | } 168 | } 169 | 170 | -------------------------------------------------------------------------------- /InputHandlerPattern.js: -------------------------------------------------------------------------------- 1 | // attach this script to any GameObject 2 | // in most cases this sits on the object that should be controlled via input 3 | // this pattern example shows how to get every input from a players controller 4 | // there is no GUI showing the results as I wanted to make this simple, reusable and clean 5 | 6 | /* INSPECTOR */ 7 | 8 | // do we want to scan for trigger and d-pad button events ? 9 | var continuousScan : boolean = true; 10 | 11 | // the player we want to get input for 12 | var player : OuyaPlayer = OuyaPlayer.P01; 13 | 14 | // the platform we are working on (installation editor) 15 | var editorWorkPlatform : EditorWorkPlatform = EditorWorkPlatform.MacOS; 16 | 17 | // the type of deadzone we want to use for convenience access 18 | var deadzoneType : DeadzoneType = DeadzoneType.CircularClip; 19 | 20 | // the size of the deadzone 21 | var deadzone : float = 0.25f; 22 | var triggerTreshold : float = 0.2f; 23 | 24 | 25 | /* ----------------------------------------------------------------------------------- 26 | * INITIAL SETUP 27 | */ 28 | 29 | function Start() 30 | { 31 | // set the editor platform to get correct input while testing in the editor 32 | OuyaInput.SetEditorPlatform(editorWorkPlatform); 33 | 34 | // OPTIONAL: set button state scanning to receive input state events for trigger and d-pads 35 | OuyaInput.SetContinuousScanning(continuousScan); 36 | 37 | // OPTIONAL: define the deadzone if you want to use advanced joystick and trigger access 38 | OuyaInput.SetDeadzone(deadzoneType, deadzone); 39 | OuyaInput.SetTriggerTreshold(triggerTreshold); 40 | 41 | // do one controller update here to get everything started as soon as possible 42 | OuyaInput.UpdateControllers(); 43 | } 44 | 45 | 46 | /* ----------------------------------------------------------------------------------- 47 | * UPDATE CYCLE 48 | */ 49 | 50 | function Update() 51 | { 52 | /* UPDATE CONTROLERS */ 53 | // IMPORTANT! update the controllers here for best results 54 | OuyaInput.UpdateControllers(); 55 | 56 | /* GET VALUES FOR CONTROLLER AXES */ 57 | 58 | // left joystick 59 | var x_Axis_LeftStick : float = OuyaInput.GetAxis(OuyaAxis.LX, player); 60 | var y_Axis_LeftStick : float = OuyaInput.GetAxis(OuyaAxis.LY, player); 61 | 62 | // right joystick 63 | var x_Axis_RightStick : float = OuyaInput.GetAxis(OuyaAxis.RX, player); 64 | var y_Axis_RightStick : float = OuyaInput.GetAxis(OuyaAxis.RY, player); 65 | 66 | // d-pad 67 | var x_Axis_DPad : float= OuyaInput.GetAxis(OuyaAxis.DX, player); 68 | var y_Axis_DPad : float= OuyaInput.GetAxis(OuyaAxis.DY, player); 69 | 70 | // triggers 71 | var axis_LeftTrigger : float = OuyaInput.GetAxis(OuyaAxis.LT, player); 72 | var axis_RightTrigger : float= OuyaInput.GetAxis(OuyaAxis.RT, player); 73 | 74 | // examples for deadzone clipping (we can choose between three types) 75 | var leftStickInput : Vector2 = OuyaInput.CheckDeadzoneCircular(x_Axis_LeftStick, y_Axis_LeftStick, deadzone); 76 | var rightStickInput : Vector2= OuyaInput.CheckDeadzoneRescaled(x_Axis_RightStick, y_Axis_RightStick, deadzone); 77 | var dPadInput : Vector2= OuyaInput.CheckDeadzoneRescaled(x_Axis_DPad, y_Axis_DPad, deadzone); 78 | 79 | /* GET ADVANCED JOYSTICK AND TRIGGER INPUT WITH DEADZONE MAPPING */ 80 | 81 | // examples for easy (or precision) joystick input 82 | var leftJoystick : Vector2 = OuyaInput.GetJoystick(OuyaJoystick.LeftStick, player); 83 | var rightJoystick : Vector2 = OuyaInput.GetJoystick(OuyaJoystick.RightStick, player); 84 | var dPad : Vector2 = OuyaInput.GetJoystick(OuyaJoystick.DPad, player); 85 | 86 | // examples for easy (or precision) trigger input 87 | var leftTrigger : float = OuyaInput.GetTrigger(OuyaTrigger.Left, player); 88 | var rightTrigger : float = OuyaInput.GetTrigger(OuyaTrigger.Right, player); 89 | 90 | /* GET PRESSED STATES FOR CONTROLLER BUTTONS */ 91 | 92 | // O U Y A buttons 93 | var pressed_O : boolean = OuyaInput.GetButton(OuyaButton.O, player); 94 | var pressed_U : boolean = OuyaInput.GetButton(OuyaButton.U, player); 95 | var pressed_Y : boolean = OuyaInput.GetButton(OuyaButton.Y, player); 96 | var pressed_A : boolean = OuyaInput.GetButton(OuyaButton.A, player); 97 | 98 | // joystick click down buttons 99 | var pressed_LeftStick : boolean = OuyaInput.GetButton(OuyaButton.L3, player); 100 | var pressed_RightStick : boolean = OuyaInput.GetButton(OuyaButton.R3, player); 101 | 102 | // trigger buttons 103 | var pressed_LeftTrigger : boolean = OuyaInput.GetButton(OuyaButton.LT, player); 104 | var pressed_RightTrigger : boolean = OuyaInput.GetButton(OuyaButton.RT, player); 105 | 106 | // center buttons 107 | var pressed_Start : boolean = OuyaInput.GetButton(OuyaButton.START, player); 108 | var pressed_Select : boolean = OuyaInput.GetButton(OuyaButton.SELECT, player); 109 | var pressed_System : boolean = OuyaInput.GetButton(OuyaButton.SYSTEM, player); 110 | 111 | /* GET DOWN EVENTS FOR CONTROLLER BUTTONS */ 112 | 113 | // we need to have OuyaInput.SetContinuousScanning(true) in Start() 114 | // some controllers might work without this but we want to make sure 115 | if (continuousScan) 116 | { 117 | // O U Y A buttons 118 | var down_O : boolean = OuyaInput.GetButtonDown(OuyaButton.O, player); 119 | var down_U : boolean = OuyaInput.GetButtonDown(OuyaButton.U, player); 120 | var down_Y : boolean= OuyaInput.GetButtonDown(OuyaButton.Y, player); 121 | var down_A : boolean= OuyaInput.GetButtonDown(OuyaButton.A, player); 122 | 123 | // joystick click down buttons 124 | var down_LeftStick : boolean = OuyaInput.GetButtonDown(OuyaButton.L3, player); 125 | var down_RightStick : boolean = OuyaInput.GetButtonDown(OuyaButton.R3, player); 126 | 127 | // trigger buttons 128 | var down_LeftTrigger : boolean = OuyaInput.GetButtonDown(OuyaButton.LT, player); 129 | var down_RightTrigger : boolean = OuyaInput.GetButtonDown(OuyaButton.RT, player); 130 | 131 | // center buttons 132 | var down_Start : boolean = OuyaInput.GetButtonDown(OuyaButton.START, player); 133 | var down_Select : boolean = OuyaInput.GetButtonDown(OuyaButton.SELECT, player); 134 | var down_System : boolean = OuyaInput.GetButtonDown(OuyaButton.SYSTEM, player); 135 | } 136 | 137 | /* GET UP (RELEASE) EVENTS FOR CONTROLLER BUTTONS */ 138 | 139 | // we need to have OuyaInput.SetContinuousScanning(true) in Start() 140 | // some controllers might work without this but we want to make sure 141 | if (continuousScan) 142 | { 143 | // O U Y A buttons 144 | var up_O : boolean = OuyaInput.GetButtonUp(OuyaButton.O, player); 145 | var up_U : boolean = OuyaInput.GetButtonUp(OuyaButton.U, player); 146 | var up_Y : boolean = OuyaInput.GetButtonUp(OuyaButton.Y, player); 147 | var up_A : boolean = OuyaInput.GetButtonUp(OuyaButton.A, player); 148 | 149 | // joystick click down buttons 150 | var up_LeftStick : boolean = OuyaInput.GetButtonUp(OuyaButton.L3, player); 151 | var up_RightStick : boolean= OuyaInput.GetButtonUp(OuyaButton.R3, player); 152 | 153 | // trigger buttons 154 | var up_LeftTrigger : boolean = OuyaInput.GetButtonUp(OuyaButton.LT, player); 155 | var up_RightTrigger : boolean = OuyaInput.GetButtonUp(OuyaButton.RT, player); 156 | 157 | // center buttons 158 | var up_Start : boolean = OuyaInput.GetButtonUp(OuyaButton.START, player); 159 | var up_Select : boolean = OuyaInput.GetButtonUp(OuyaButton.SELECT, player); 160 | var up_System : boolean= OuyaInput.GetButtonUp(OuyaButton.SYSTEM, player); 161 | } 162 | } -------------------------------------------------------------------------------- /OuyaInput.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | 4 | /* GLOBAL ENUM DATA TYPES */ 5 | // defining button states and events 6 | // pressed: the button is pressed down 7 | // upFrame: the moment (frame) the button goes up 8 | // downFrame: the moment (frame) the button goes down 9 | public enum ButtonAction {Pressed, UpFrame, DownFrame} 10 | // describing the Ouya controller buttons 11 | public enum OuyaButton {O, U, Y, A, LB, RB, L3, R3, LT, RT, DU, DD, DL, DR, START, SELECT, SYSTEM} 12 | // describing the Ouya controller axis 13 | public enum OuyaAxis {LX, LY, RX, RY, LT, RT, DX, DY} 14 | // describing the three joystick types 15 | public enum OuyaJoystick {LeftStick, RightStick, DPad} 16 | // describing the two triggers on the Ouya controller 17 | public enum OuyaTrigger {Left, Right} 18 | // describing players on the console 19 | public enum OuyaPlayer {None = 0, P01 = 1, P02 = 2, P03 = 3, P04 = 4, P05 = 5, P06 = 6, P07 = 7, P08 = 8, P09 = 9, P10 = 10, P11 = 11} 20 | // defining known controller types 21 | public enum OuyaControllerType {Broadcom, GameStick, MogaPro, Ouya, PS3, XBox360, TattieBogle, Unknown, None} 22 | // defining test platform types 23 | public enum EditorWorkPlatform {MacOS, Windows} 24 | // defining deadzone types 25 | public enum DeadzoneType {AxialClip, CircularClip, CircularMap} 26 | // defining angular quadrants of joystick input 27 | public enum Quadrant {I, II, III, IV, OnXPos, OnXNeg, OnYPos, OnYNeg, Zero} 28 | 29 | public static class OuyaInput 30 | { 31 | /* PROPERTIES */ 32 | // adjust this value to set the check interval (consider performance) 33 | // this is just for checking if a controller was unplugged or added 34 | private const int playersMax = 11; 35 | 36 | // setting for platform specific djustments 37 | private static float plugCheckInterval = 3; 38 | private static bool scanContinuously = true; 39 | private static float deadzoneRadius = 0.25f; 40 | private static float triggerThreshold = 0.10f; 41 | 42 | private static EditorWorkPlatform editorWorkPlatform = EditorWorkPlatform.MacOS; 43 | private static DeadzoneType deadzoneType = DeadzoneType.CircularClip; 44 | 45 | /* TEMPORARY */ 46 | // the time of the last joystick lis update 47 | private static float lastPlugCheckTime = 0; 48 | // a list of all available controller names 49 | private static string[] controllerNames = null; 50 | // a list of all available controller types derived from names 51 | private static OuyaControllerType[] controllerTypes = null; 52 | // a list of active controller mapping containers 53 | private static PlayerController[] playerControllers = null; 54 | // counting all connected controllers 55 | private static int controllerCount = 0; 56 | 57 | 58 | /* ----------------------------------------------------------------------------------- 59 | * INITIALIZATION 60 | */ 61 | 62 | static OuyaInput() { 63 | /* static constructor 64 | */ 65 | // create an array of classes caching input mapping strings 66 | playerControllers = new PlayerController[playersMax]; 67 | // create an array for storing the controller types 68 | controllerTypes = new OuyaControllerType[playersMax]; 69 | // initialize every field of that array 70 | for (int i = 0; i < playersMax; i++) { 71 | controllerTypes[i] = OuyaControllerType.None; 72 | } 73 | } 74 | 75 | /* ----------------------------------------------------------------------------------- 76 | * NESTED TRANSLATOR CONTAINERS 77 | */ 78 | 79 | #region CACHED MAPPING CLASS 80 | 81 | private class PlayerController { 82 | /* container class caching the axis name strings for one controller 83 | * we use that to cache mapping strings and prevent gabage collection 84 | */ 85 | public OuyaPlayer player; 86 | public OuyaControllerType controllerType; 87 | 88 | // axis strings caching 89 | public string map_LX = null; 90 | public string map_LY = null; 91 | public string map_RX = null; 92 | public string map_RY = null; 93 | public string map_LT = null; 94 | public string map_RT = null; 95 | public string map_DX = null; 96 | public string map_DY = null; 97 | 98 | // invert flags for axis 99 | public bool invert_LX = false; 100 | public bool invert_LY = false; 101 | public bool invert_RX = false; 102 | public bool invert_RY = false; 103 | public bool invert_LT = false; 104 | public bool invert_RT = false; 105 | public bool invert_DX = false; 106 | public bool invert_DY = false; 107 | 108 | // flags for trigger button events from axis 109 | public bool upEventLT = false; 110 | public bool upEventRT = false; 111 | public bool downEventLT = false; 112 | public bool downEventRT = false; 113 | public bool downStateLT = false; 114 | public bool downStateRT = false; 115 | 116 | private bool initAxisLT = false; 117 | private bool initAxisRT = false; 118 | 119 | // flags for d-pad button events from axis 120 | public bool upEventDU = false; 121 | public bool upEventDD = false; 122 | public bool upEventDR = false; 123 | public bool upEventDL = false; 124 | public bool downEventDU = false; 125 | public bool downEventDD = false; 126 | public bool downEventDR = false; 127 | public bool downEventDL = false; 128 | public bool downStateDU = false; 129 | public bool downStateDD = false; 130 | public bool downStateDR = false; 131 | public bool downStateDL = false; 132 | 133 | 134 | public PlayerController(OuyaPlayer player, OuyaControllerType controllerType) { 135 | /* constructor 136 | */ 137 | this.controllerType = controllerType; 138 | this.player = player; 139 | } 140 | 141 | public bool checkControllerType(OuyaControllerType againstType) { 142 | /* returns true if the controller type equals that of the given one 143 | */ 144 | if (againstType == controllerType) return true; 145 | else return false; 146 | } 147 | 148 | public void setController(OuyaPlayer player, OuyaControllerType controllerType) { 149 | /* allows to reinitialize the ID of an existing controller mapping 150 | */ 151 | this.controllerType = controllerType; 152 | this.player = player; 153 | } 154 | 155 | public string getAxisID(OuyaAxis ouyaButton) { 156 | /* returns the cached axis ID called for 157 | */ 158 | switch (ouyaButton) { 159 | case OuyaAxis.LX: return map_LX; 160 | case OuyaAxis.LY: return map_LY; 161 | case OuyaAxis.RX: return map_RX; 162 | case OuyaAxis.RY: return map_RY; 163 | case OuyaAxis.LT: return map_LT; 164 | case OuyaAxis.RT: return map_RT; 165 | case OuyaAxis.DX: return map_DX; 166 | case OuyaAxis.DY: return map_DY; 167 | default: return null; 168 | } 169 | } 170 | 171 | public bool getAxisInvert(OuyaAxis ouyaButton) { 172 | /* returns a flag indicating whether the axis needs inversion 173 | */ 174 | switch (ouyaButton) { 175 | case OuyaAxis.LX: return invert_LX; 176 | case OuyaAxis.LY: return invert_LY; 177 | case OuyaAxis.RX: return invert_RX; 178 | case OuyaAxis.RY: return invert_RY; 179 | case OuyaAxis.LT: return invert_LT; 180 | case OuyaAxis.RT: return invert_RT; 181 | case OuyaAxis.DX: return invert_DX; 182 | case OuyaAxis.DY: return invert_DY; 183 | default: return false; 184 | } 185 | } 186 | 187 | public float rangeMapTriggerAxis(float axisValue, OuyaAxis triggerAxis) { 188 | /* this remapping method allows to convert trigger axis values 189 | * we want to bring all trigger axis values into arange on 0 to 1 190 | * this is needed for the MacOSX XBOX360 driver which provides values from -1 to 1 191 | */ 192 | // check if the trigger axis was initialized 193 | switch (triggerAxis) { 194 | case OuyaAxis.LT: if (!initAxisLT && axisValue != 0f) initAxisLT = true; break; 195 | case OuyaAxis.RT: if (!initAxisRT && axisValue != 0f) initAxisRT = true; break; 196 | } 197 | // we check if the controller we have need range mapping 198 | switch (controllerType) { 199 | #if UNITY_EDITOR || UNITY_STANDALONE_WIN 200 | case OuyaControllerType.Ouya: 201 | #endif 202 | case OuyaControllerType.TattieBogle: 203 | // remap values from range -1to1 onto range 0to1 204 | switch (triggerAxis) { 205 | case OuyaAxis.LT: 206 | // we only retrun a converted value if the trigger was initialized 207 | // otherwise we would get out 0.5 initially without pressing the trigger 208 | if (initAxisLT) return ((axisValue + 1) / 2f); 209 | else return 0f; 210 | case OuyaAxis.RT: 211 | // we only retrun a converted value if the trigger was initialized 212 | // otherwise we would get out 0.5 initially without pressing the trigger 213 | if (initAxisRT) return ((axisValue + 1) / 2f); 214 | else return 0f; 215 | default: return 0f; 216 | } 217 | default: 218 | // just retrun the value without changes 219 | return axisValue; 220 | } 221 | } 222 | 223 | public void scanController() { 224 | /* this method can be called every frame to gather button events for single frames 225 | * it is the core of a button state manager 226 | */ 227 | // we start with consuming all older events 228 | downEventLT = false; upEventLT = false; 229 | downEventRT = false; upEventRT = false; 230 | downEventDU = false; upEventDU = false; 231 | downEventDD = false; upEventDD = false; 232 | downEventDR = false; upEventDR = false; 233 | downEventDL = false; upEventDL = false; 234 | 235 | // prepare a field for temporary storage 236 | bool down = false; 237 | 238 | /* LEFT TRIGGER */ 239 | // get the current state of the left trigger 240 | down = OuyaInput.GetButton(OuyaButton.LT, ButtonAction.Pressed, player); 241 | // compare that state to the state of the last frame 242 | if (down) { 243 | // set an down event if the button was not down before 244 | if (!downStateLT) {downStateLT = true; downEventLT = true;} 245 | } else { 246 | // set an up event if the button was down before 247 | if (downStateLT) {downStateLT = false; upEventLT = true;} 248 | } 249 | /* RIGHT TRIGGER */ 250 | // get the current state of the right trigger 251 | down = OuyaInput.GetButton(OuyaButton.RT, ButtonAction.Pressed, player); 252 | // compare that state to the state of the last frame 253 | if (down) { 254 | // set an down event if the button was not down before 255 | if (!downStateRT) {downStateRT = true; downEventRT = true;} 256 | } else { 257 | // set an up event if the button was down before 258 | if (downStateRT) {downStateRT = false; upEventRT = true;} 259 | } 260 | /* D-PAD UP */ 261 | // get the current state of the d-pad up 262 | down = OuyaInput.GetButton(OuyaButton.DU, ButtonAction.Pressed, player); 263 | // compare that state to the state of the last frame 264 | if (down) { 265 | // set an down event if the button was not down before 266 | if (!downStateDU) {downStateDU = true; downEventDU = true;} 267 | } else { 268 | // set an up event if the button was down before 269 | if (downStateDU) {downStateDU = false; upEventDU = true;} 270 | } 271 | /* D-PAD DOWN */ 272 | // get the current state of the d-pad up 273 | down = OuyaInput.GetButton(OuyaButton.DD, ButtonAction.Pressed, player); 274 | // compare that state to the state of the last frame 275 | if (down) { 276 | // set an down event if the button was not down before 277 | if (!downStateDD) {downStateDD = true; downEventDD = true;} 278 | } else { 279 | // set an up event if the button was down before 280 | if (downStateDD) {downStateDD = false; upEventDD = true;} 281 | } 282 | /* D-PAD RIGHT */ 283 | // get the current state of the d-pad up 284 | down = OuyaInput.GetButton(OuyaButton.DR, ButtonAction.Pressed, player); 285 | // compare that state to the state of the last frame 286 | if (down) { 287 | // set an down event if the button was not down before 288 | if (!downStateDR) {downStateDR = true; downEventDR = true;} 289 | } else { 290 | // set an up event if the button was down before 291 | if (downStateDR) {downStateDR = false; upEventDR = true;} 292 | } 293 | /* D-PAD LEFT */ 294 | // get the current state of the d-pad up 295 | down = OuyaInput.GetButton(OuyaButton.DL, ButtonAction.Pressed, player); 296 | // compare that state to the state of the last frame 297 | if (down) { 298 | // set an down event if the button was not down before 299 | if (!downStateDL) {downStateDL = true; downEventDL = true;} 300 | } else { 301 | // set an up event if the button was down before 302 | if (downStateDL) {downStateDL = false; upEventDL = true;} 303 | } 304 | } 305 | 306 | public void resetControllerCache() { 307 | /* method to reset all flags we use when scanning continuously for trigger events 308 | */ 309 | downEventLT = false; upEventLT = false; downStateLT = false; 310 | downEventRT = false; upEventRT = false; downStateRT = false; 311 | 312 | upEventDU = false; downEventDU = false; downStateDU = false; 313 | upEventDD = false; downEventDD = false; downStateDD = false; 314 | upEventDR = false; downEventDR = false; downStateDR = false; 315 | upEventDL = false; downEventDL = false; downStateDL = false; 316 | } 317 | } 318 | #endregion 319 | 320 | /* ----------------------------------------------------------------------------------- 321 | * CONTROLLER UPDATE 322 | */ 323 | 324 | #region CONTROLLER SETUP & UPDATE 325 | 326 | public static void SetEditorPlatform(EditorWorkPlatform workPlatform) { 327 | /* sets a work platform for the editor 328 | * this allows to manage platform specific input for different working environments 329 | * this is necessary as precompile macros do not work for finding out on which 330 | * platform our editor is currently running – the check only standalone builds 331 | */ 332 | editorWorkPlatform = workPlatform; 333 | } 334 | 335 | public static void SetContinuousScanning(bool active) { 336 | /* allows to activate continuous controller scanning 337 | * this is needed to retreive ButtonUp and BottonDown events for triggers and d-pads 338 | */ 339 | scanContinuously = active; 340 | } 341 | 342 | public static void SetPlugCheckInterval(float seconds) { 343 | /* allows to adjust the interval for controller plug checks 344 | * the smaller the interval is the earlier new controllers get noticed 345 | */ 346 | plugCheckInterval = seconds; 347 | } 348 | 349 | public static void UpdateControllers() { 350 | /* method to check if joystick where plugged or unplugged 351 | * updates the list of joysticks 352 | * this should be called at Start() and in Update() 353 | */ 354 | // we only do a joystick plug check every 3 seconds 355 | if ((Time.time - lastPlugCheckTime) > plugCheckInterval) { 356 | // store the time of the current plug check 357 | lastPlugCheckTime = Time.time; 358 | 359 | /* GET CONTROLLERS */ 360 | // get joystick names from Unity 361 | controllerNames = Input.GetJoystickNames(); 362 | // count the connected controllers 363 | controllerCount = controllerNames.Length; 364 | 365 | /* MAP CONTROLLERS */ 366 | // create a controller types eum array 367 | // we do that to avoid string comparissons every frame for each axis 368 | // the mirror conversion into enums avoids excessive string creation and GC 369 | if (controllerNames != null) { 370 | // convert each string in the array into the corresponding enum 371 | // create mapping container objects for each new controller 372 | for (int i = 0; i < controllerCount; i++) 373 | { 374 | // set the controller type for each controller name 375 | controllerTypes[i] = findControllerType(i, controllerNames[i]); 376 | 377 | /* (RE)USE EXISTING MAPPING */ 378 | // check if we already have a map for this controller 379 | if (playerControllers[i] != null) 380 | { 381 | // if we have a map we make sure that it is still of the same controller type 382 | if (!playerControllers[i].checkControllerType(controllerTypes[i])) { 383 | // reinitialize the type of the existing mapping if needed 384 | playerControllers[i].setController((OuyaPlayer)(i+1), controllerTypes[i]); 385 | // redo the mapping in the existing container for the new controller 386 | mapController(playerControllers[i]); 387 | } 388 | } 389 | /* CREATE NEW MAPPING */ 390 | else { 391 | // if not we create a new one 392 | playerControllers[i] = new PlayerController((OuyaPlayer)(i+1), controllerTypes[i]); 393 | // set the mappings for the new controller 394 | mapController(playerControllers[i]); 395 | } 396 | } 397 | // we reset all the controller type fields that are not used anymore 398 | for (int i = controllerCount; i < playersMax; i++) { 399 | controllerTypes[i] = OuyaControllerType.None; 400 | } 401 | } 402 | /* CLEAR CONTROLLER MAPS */ 403 | else { 404 | // if we found no controller names we reset the counter 405 | controllerCount = 0; 406 | 407 | for (int i = 0; i < playersMax; i++) { 408 | // we reset all controller types in the array 409 | controllerTypes[i] = OuyaControllerType.None; 410 | // we also clear all mappings that are not used anymore 411 | playerControllers[i] = null; 412 | } 413 | } 414 | } 415 | /* CONTINUOUS JOYSTICK LIST */ 416 | // this block is a state manager that allows to get button events for native axes buttons 417 | if (scanContinuously && controllerCount > 0) 418 | { 419 | // scan controllers to gather button down or up events for triggers 420 | for (int i = 0; i < controllerCount; i++) { 421 | playerControllers[i].scanController(); 422 | } 423 | } 424 | } 425 | 426 | 427 | public static void ResetInput() { 428 | /* resets the Unity input as well as any cached button events here 429 | */ 430 | // reset the axis input in Unity 431 | Input.ResetInputAxes(); 432 | 433 | // reset all the player controllers 434 | for (int i = 0; i < playerControllers.Length; i++) { 435 | // check if this controller mapping exists 436 | if (playerControllers[i] != null) { 437 | // reset the controller mapping in case 438 | playerControllers[i].resetControllerCache(); 439 | } 440 | } 441 | } 442 | #endregion 443 | 444 | /* ----------------------------------------------------------------------------------- 445 | * CONTROLLER MAPPING CACHE 446 | */ 447 | 448 | #region CONTROLLER MAPPING 449 | 450 | private static OuyaControllerType findControllerType(int index, string controllerName) { 451 | /* a helper for the updateJoystickList() method 452 | * converts controller string names into enum descriptions 453 | */ 454 | switch (controllerName.ToUpper()) { 455 | case "BROADCOM BLUETOOTH HID": 456 | controllerTypes[index] = OuyaControllerType.Broadcom; 457 | return OuyaControllerType.Broadcom; 458 | case "MOGA PRO HID": 459 | controllerTypes[index] = OuyaControllerType.MogaPro; 460 | return OuyaControllerType.MogaPro; 461 | case "OUYA GAME CONTROLLER": 462 | controllerTypes[index] = OuyaControllerType.Ouya; 463 | return OuyaControllerType.Ouya; 464 | case "GAMESTICK CONTROLLER 1": 465 | case "GAMESTICK CONTROLLER 2": 466 | case "GAMESTICK CONTROLLER 3": 467 | case "GAMESTICK CONTROLLER 4": 468 | controllerTypes[index] = OuyaControllerType.GameStick; 469 | return OuyaControllerType.GameStick; 470 | case "XBOX 360 WIRELESS RECEIVER": 471 | case "CONTROLLER (AFTERGLOW GAMEPAD FOR XBOX 360)": 472 | case "CONTROLLER (ROCK CANDY GAMEPAD FOR XBOX 360)": 473 | case "CONTROLLER (XBOX 360 WIRELESS RECEIVER FOR WINDOWS)": 474 | case "MICROSOFT X-BOX 360 PAD": 475 | case "CONTROLLER (XBOX 360 FOR WINDOWS)": 476 | case "CONTROLLER (XBOX360 GAMEPAD)": 477 | case "XBOX 360 FOR WINDOWS (CONTROLLER)": 478 | controllerTypes[index] = OuyaControllerType.XBox360; 479 | return OuyaControllerType.XBox360; 480 | case "MOTIONINJOY VIRTUAL GAME CONTROLLER": 481 | case "SONY PLAYSTATION(R)3 CONTROLLER": 482 | case "PLAYSTATION(R)3 CONTROLLER": 483 | controllerTypes[index] = OuyaControllerType.PS3; 484 | return OuyaControllerType.PS3; 485 | case "MICROSOFT WIRELESS 360 CONTROLLER": 486 | case "": 487 | 488 | #if UNITY_EDITOR || UNITY_STANDALONE_OSX 489 | controllerTypes[index] = OuyaControllerType.TattieBogle; 490 | return OuyaControllerType.TattieBogle; 491 | #else 492 | controllerTypes[index] = OuyaControllerType.Unknown; 493 | return OuyaControllerType.Unknown; 494 | #endif 495 | default: 496 | controllerTypes[index] = OuyaControllerType.Unknown; 497 | return OuyaControllerType.Unknown; 498 | } 499 | } 500 | 501 | private static void mapController(PlayerController playerController) { 502 | /* constructs a specific string for every axis the controller type has 503 | * these strings can be used to acces Unity input directly later 504 | * the strins are stored in the given mapping container 505 | * we also set invert flags for each axis here 506 | * ToDo test and adjust all invert flags 507 | */ 508 | // this is a good point to reset the input in Unity 509 | Input.ResetInputAxes(); 510 | // we also reset all cached button states 511 | playerController.resetControllerCache(); 512 | 513 | // convert the player enum into an integer 514 | int player = (int)playerController.player; 515 | 516 | // construct axis name for the controller type and player number 517 | // the generic axis are different for Android ports and other platforms (Editor) 518 | // the inversed encoding for axis values is also cared for here 519 | // this is solved by precompile makros 520 | switch (playerController.controllerType) 521 | { 522 | #if !UNITY_EDITOR && UNITY_ANDROID 523 | case OuyaControllerType.Broadcom: 524 | case OuyaControllerType.MogaPro: 525 | playerController.map_LX = string.Format("Joy{0} Axis 1", player); playerController.invert_LX = false; 526 | playerController.map_LY = string.Format("Joy{0} Axis 2", player); playerController.invert_LY = true; 527 | playerController.map_RX = string.Format("Joy{0} Axis 3", player); playerController.invert_RX = false; 528 | playerController.map_RY = string.Format("Joy{0} Axis 4", player); playerController.invert_RY = false; 529 | playerController.map_LT = string.Format("Joy{0} Axis 8", player); playerController.invert_LT = false; 530 | playerController.map_RT = string.Format("Joy{0} Axis 7", player); playerController.invert_RT = false; 531 | playerController.map_DX = string.Format("Joy{0} Axis 5", player); playerController.invert_DX = false; 532 | playerController.map_DY = string.Format("Joy{0} Axis 6", player); playerController.invert_DY = false; 533 | break; 534 | 535 | case OuyaControllerType.GameStick: 536 | playerController.map_LX = string.Format("Joy{0} Axis 1", player); playerController.invert_LX = false; // checked 537 | playerController.map_LY = string.Format("Joy{0} Axis 2", player); playerController.invert_LY = true; // checked 538 | playerController.map_RX = string.Format("Joy{0} Axis 3", player); playerController.invert_RX = false; // checked 539 | playerController.map_RY = string.Format("Joy{0} Axis 4", player); playerController.invert_RY = true; // checked 540 | playerController.map_DX = string.Format("Joy{0} Axis 5", player); playerController.invert_DX = false; // checked 541 | playerController.map_DY = string.Format("Joy{0} Axis 6", player); playerController.invert_DY = true; // checked 542 | // the GameStick controller has no triggers at all 543 | playerController.map_LT = null; playerController.invert_LT = false; 544 | playerController.map_RT = null; playerController.invert_RT = false; 545 | break; 546 | #endif 547 | case OuyaControllerType.Ouya: 548 | #if !UNITY_EDITOR && UNITY_ANDROID 549 | playerController.map_LX = string.Format("Joy{0} Axis 1", player); playerController.invert_LX = false; // checked 550 | playerController.map_LY = string.Format("Joy{0} Axis 2", player); playerController.invert_LY = true; // checked 551 | playerController.map_RX = string.Format("Joy{0} Axis 3", player); playerController.invert_RX = false; // checked 552 | playerController.map_RY = string.Format("Joy{0} Axis 4", player); playerController.invert_RY = true; // checked 553 | playerController.map_LT = string.Format("Joy{0} Axis 5", player); playerController.invert_LT = false; // checked 554 | playerController.map_RT = string.Format("Joy{0} Axis 6", player); playerController.invert_RT = false; // checked 555 | // the dpad is not analog and therefore not mapped as an axis 556 | playerController.map_DX = null; playerController.invert_DX = false; 557 | playerController.map_DY = null; playerController.invert_DY = false; 558 | #else 559 | playerController.map_LX = string.Format("Joy{0} Axis 1", player); playerController.invert_LX = false; // checked 560 | playerController.map_LY = string.Format("Joy{0} Axis 2", player); playerController.invert_LY = true; // checked 561 | playerController.map_RX = string.Format("Joy{0} Axis 4", player); playerController.invert_RX = false; // checked 562 | playerController.map_RY = string.Format("Joy{0} Axis 5", player); playerController.invert_RY = true; // checked 563 | playerController.map_LT = string.Format("Joy{0} Axis 3", player); playerController.invert_LT = false; // checked 564 | playerController.map_RT = string.Format("Joy{0} Axis 6", player); playerController.invert_RT = false; // checked 565 | // the dpad is not analog and therefore not mapped as an axis 566 | playerController.map_DX = null; playerController.invert_DX = false; 567 | playerController.map_DY = null; playerController.invert_DY = false; 568 | #endif 569 | break; 570 | case OuyaControllerType.XBox360: 571 | #if !UNITY_EDITOR && UNITY_ANDROID 572 | playerController.map_LX = string.Format("Joy{0} Axis 1", player); playerController.invert_LX = false; // checked 573 | playerController.map_LY = string.Format("Joy{0} Axis 2", player); playerController.invert_LY = true; // checked 574 | playerController.map_RX = string.Format("Joy{0} Axis 3", player); playerController.invert_RX = false; // checked 575 | playerController.map_RY = string.Format("Joy{0} Axis 4", player); playerController.invert_RY = true; // checked 576 | playerController.map_LT = string.Format("Joy{0} Axis 7", player); playerController.invert_LT = false; // checked 577 | playerController.map_RT = string.Format("Joy{0} Axis 8", player); playerController.invert_RT = false; // checked 578 | playerController.map_DX = string.Format("Joy{0} Axis 5", player); playerController.invert_DX = false; // checked 579 | playerController.map_DY = string.Format("Joy{0} Axis 6", player); playerController.invert_DY = true; // checked 580 | #else 581 | playerController.map_LX = string.Format("Joy{0} Axis 1", player); playerController.invert_LX = false; // checked 582 | playerController.map_LY = string.Format("Joy{0} Axis 2", player); playerController.invert_LY = true; // checked 583 | playerController.map_RX = string.Format("Joy{0} Axis 4", player); playerController.invert_RX = false; // checked 584 | playerController.map_RY = string.Format("Joy{0} Axis 5", player); playerController.invert_RY = true; // checked 585 | playerController.map_LT = string.Format("Joy{0} Axis 9", player); playerController.invert_LT = false; // checked 586 | playerController.map_RT = string.Format("Joy{0} Axis 10", player); playerController.invert_RT = false; // checked 587 | playerController.map_DX = string.Format("Joy{0} Axis 6", player); playerController.invert_DX = false; // checked 588 | playerController.map_DY = string.Format("Joy{0} Axis 7", player); playerController.invert_DY = false; // checked 589 | #endif 590 | break; 591 | case OuyaControllerType.PS3: 592 | #if !UNITY_EDITOR && UNITY_ANDROID 593 | playerController.map_LX = string.Format("Joy{0} Axis 1", player); playerController.invert_LX = false; // checked 594 | playerController.map_LY = string.Format("Joy{0} Axis 2", player); playerController.invert_LY = true; // checked 595 | playerController.map_RX = string.Format("Joy{0} Axis 3", player); playerController.invert_RX = false; // checked 596 | playerController.map_RY = string.Format("Joy{0} Axis 4", player); playerController.invert_RY = true; // checked 597 | playerController.map_LT = string.Format("Joy{0} Axis 5", player); playerController.invert_LT = false; // checked 598 | playerController.map_RT = string.Format("Joy{0} Axis 6", player); playerController.invert_RT = false; // checked 599 | // the dpad is not analog and therefore not mapped as an axis 600 | playerController.map_DX = null; playerController.invert_DX = false; 601 | playerController.map_DY = null; playerController.invert_DY = false; 602 | #elif !UNITY_EDITOR && UNITY_STANDALONE_WIN 603 | playerController.map_LX = string.Format("Joy{0} Axis 1", player); playerController.invert_LX = false; // checked 604 | playerController.map_LY = string.Format("Joy{0} Axis 2", player); playerController.invert_LY = true; // checked 605 | playerController.map_RX = string.Format("Joy{0} Axis 4", player); playerController.invert_RX = false; // checked 606 | playerController.map_RY = string.Format("Joy{0} Axis 5", player); playerController.invert_RY = true; // checked 607 | playerController.map_LT = string.Format("Joy{0} Axis 3", player); playerController.invert_LT = false; // checked 608 | playerController.map_RT = string.Format("Joy{0} Axis 6", player); playerController.invert_RT = false; // checked 609 | // the dpad is not analog and therefore not mapped as an axis 610 | playerController.map_DX = null; playerController.invert_DX = false; 611 | playerController.map_DY = null; playerController.invert_DY = false; 612 | #elif !UNITY_EDITOR && UNITY_STANDALONE_OSX 613 | playerController.map_LX = string.Format("Joy{0} Axis 1", player); playerController.invert_LX = false; // checked 614 | playerController.map_LY = string.Format("Joy{0} Axis 2", player); playerController.invert_LY = true; // checked 615 | playerController.map_RX = string.Format("Joy{0} Axis 3", player); playerController.invert_RX = false; // checked 616 | playerController.map_RY = string.Format("Joy{0} Axis 4", player); playerController.invert_RY = true; // checked 617 | // d-pad and triggers are not analog and therefore not mapped as an axis 618 | playerController.map_LT = null; playerController.invert_LT = false; 619 | playerController.map_RT = null; playerController.invert_RT = false; 620 | playerController.map_DX = null; playerController.invert_DX = false; 621 | playerController.map_DY = null; playerController.invert_DY = false; 622 | #elif UNITY_EDITOR 623 | // in the editor we have to set on which platform we are working 624 | // different editor working environments are not covered by Unity's macros 625 | if (editorWorkPlatform == EditorWorkPlatform.MacOS) // MacOSX standard Bluetooth connection 626 | { 627 | playerController.map_LX = string.Format("Joy{0} Axis 1", player); playerController.invert_LX = false; // checked 628 | playerController.map_LY = string.Format("Joy{0} Axis 2", player); playerController.invert_LY = true; // checked 629 | playerController.map_RX = string.Format("Joy{0} Axis 3", player); playerController.invert_RX = false; // checked 630 | playerController.map_RY = string.Format("Joy{0} Axis 4", player); playerController.invert_RY = true; // checked 631 | // d-pad and triggers are not analog and therefore not mapped as an axis 632 | playerController.map_LT = null; playerController.invert_LT = false; 633 | playerController.map_RT = null; playerController.invert_RT = false; 634 | playerController.map_DX = null; playerController.invert_DX = false; 635 | playerController.map_DY = null; playerController.invert_DY = false; 636 | } 637 | else // this is for Windows7 using the MotionInJoy driver with custom settings 638 | { 639 | playerController.map_LX = string.Format("Joy{0} Axis 1", player); playerController.invert_LX = false; // checked 640 | playerController.map_LY = string.Format("Joy{0} Axis 2", player); playerController.invert_LY = true; // checked 641 | playerController.map_RX = string.Format("Joy{0} Axis 4", player); playerController.invert_RX = false; // checked 642 | playerController.map_RY = string.Format("Joy{0} Axis 5", player); playerController.invert_RY = true; // checked 643 | playerController.map_LT = string.Format("Joy{0} Axis 3", player); playerController.invert_LT = false; // checked 644 | playerController.map_RT = string.Format("Joy{0} Axis 6", player); playerController.invert_RT = false; // checked 645 | // the dpad is not analog and therefore not mapped as an axis 646 | playerController.map_DX = null; playerController.invert_DX = false; 647 | playerController.map_DY = null; playerController.invert_DY = false; 648 | } 649 | #endif 650 | break; 651 | #if UNITY_EDITOR || UNITY_STANDALONE_OSX 652 | case OuyaControllerType.TattieBogle: //this is the driver for the XBOX360 controller on MacOSX 653 | playerController.map_LX = string.Format("Joy{0} Axis 1", player); playerController.invert_LX = false; // checked 654 | playerController.map_LY = string.Format("Joy{0} Axis 2", player); playerController.invert_LY = true; // checked 655 | playerController.map_RX = string.Format("Joy{0} Axis 3", player); playerController.invert_RX = false; // checked 656 | playerController.map_RY = string.Format("Joy{0} Axis 4", player); playerController.invert_RY = true; // checked 657 | playerController.map_LT = string.Format("Joy{0} Axis 5", player); playerController.invert_LT = false; // checked -1 > 1 658 | playerController.map_RT = string.Format("Joy{0} Axis 6", player); playerController.invert_RT = false; // checked -1 > 1 659 | // the dpad is not analog and therefore not mapped as an axis 660 | playerController.map_DX = null; playerController.invert_DX = false; 661 | playerController.map_DY = null; playerController.invert_DY = false; 662 | break; 663 | #endif 664 | case OuyaControllerType.Unknown: // we hope to catch any unkown bluetooth controllers 665 | playerController.map_LX = string.Format("Joy{0} Axis 1", player); playerController.invert_LX = false; 666 | playerController.map_LY = string.Format("Joy{0} Axis 2", player); playerController.invert_LY = true; 667 | playerController.map_RX = string.Format("Joy{0} Axis 3", player); playerController.invert_RX = false; 668 | playerController.map_RY = string.Format("Joy{0} Axis 4", player); playerController.invert_RY = true; 669 | playerController.map_DX = string.Format("Joy{0} Axis 5", player); playerController.invert_DX = false; 670 | playerController.map_DY = string.Format("Joy{0} Axis 6", player); playerController.invert_DY = true; 671 | playerController.map_LT = string.Format("Joy{0} Axis 7", player); playerController.invert_LT = false; 672 | playerController.map_RT = string.Format("Joy{0} Axis 8", player); playerController.invert_RT = false; 673 | break; 674 | } 675 | } 676 | #endregion 677 | 678 | /* ----------------------------------------------------------------------------------- 679 | * CONTROLLER ACCESS METHODS 680 | */ 681 | 682 | #region GENERAL CONTROLLER INFO 683 | 684 | public static bool GetControllerConnection() { 685 | /* returns if we have any controller connected 686 | * helpful for switching input types (keypoard or gamepad) according to controller availability 687 | */ 688 | if (controllerNames == null || controllerNames.Length == 0) return false; 689 | else return true; 690 | } 691 | 692 | public static string GetControllerName(OuyaPlayer player) { 693 | /* returns the Unity name of the controller for a designated player 694 | */ 695 | int index = (int)player -1; 696 | if (controllerNames == null || index >= controllerCount) return "No controller found!"; 697 | else return controllerNames[index]; 698 | } 699 | 700 | public static OuyaControllerType GetControllerType(OuyaPlayer player) { 701 | /* returns the controller type (enum) for a designated player 702 | */ 703 | int index = (int)player -1; 704 | if (controllerCount == 0) return OuyaControllerType.None; 705 | else return controllerTypes[index]; 706 | } 707 | 708 | #endregion 709 | 710 | #region AXIS STATE ACCESS 711 | 712 | public static float GetAxis(OuyaAxis axis, OuyaPlayer player) { 713 | /* for retreiving joystick axis values from mapped Unity Input 714 | */ 715 | 716 | /* NULL SECURITY */ 717 | // check if there is no joystick connected 718 | if (controllerCount == 0) return 0f; 719 | 720 | // check if there have more players than controllers 721 | // we consider that the array position is starting at 0 for player 1 722 | int playerIndex = (int)player - 1; 723 | if (playerIndex < 0 || playerIndex >= controllerCount) return 0f; 724 | 725 | // finally check if we really found a controller for the player 726 | OuyaControllerType controllerType = controllerTypes[playerIndex]; 727 | 728 | /* GET MAPPED AXIS NAME */ 729 | // prepare fields for storing the results 730 | string axisName = null; bool invert = false; 731 | 732 | // get the controller mapping for the player 733 | PlayerController playerController = playerControllers[playerIndex]; 734 | // secure that we have found a mapping 735 | if (playerController == null) return 0f; 736 | else 737 | { 738 | /* JOYSTICKS */ 739 | // get the axis name for the player controller 740 | switch (axis) { 741 | case OuyaAxis.LX: axisName = playerController.map_LX; invert = playerController.invert_LX; break; 742 | case OuyaAxis.LY: axisName = playerController.map_LY; invert = playerController.invert_LY; break; 743 | case OuyaAxis.RX: axisName = playerController.map_RX; invert = playerController.invert_RX; break; 744 | case OuyaAxis.RY: axisName = playerController.map_RY; invert = playerController.invert_RY; break; 745 | 746 | /* TRIGGERS & D-PAD */ 747 | // the dpad and triggers are sometimes treated like an axis joystick 748 | // sometimes however it is just a set of buttons and the pressure senitivity is missing 749 | // this was observed for MacOS XBOX360 (TattieBogle) / Android Ouya / Android + MacOS PS3 750 | /* LT-TRIGGER */ 751 | case OuyaAxis.LT: axisName = playerController.map_LT; invert = playerController.invert_LT; 752 | // if the trigger is treated like a button we convert button press bool flags into axis values 753 | if (axisName == null) 754 | { 755 | switch (controllerType) { 756 | case OuyaControllerType.PS3: 757 | if (GetButton(8, ButtonAction.Pressed, player)) return 1f; else return 0f; 758 | } 759 | } 760 | break; 761 | /* RT-TRIGGER */ 762 | case OuyaAxis.RT: axisName = playerController.map_RT; invert = playerController.invert_RT; 763 | // if the trigger is treated like a button we convert button press bool flags into axis values 764 | if (axisName == null) 765 | { 766 | switch (controllerType) { 767 | case OuyaControllerType.PS3: 768 | if (GetButton(9, ButtonAction.Pressed, player)) return 1f; else return 0f; 769 | } 770 | } 771 | break; 772 | /* DX-AXIS */ 773 | case OuyaAxis.DX: axisName = playerController.map_DX; invert = playerController.invert_DX; 774 | // if the dpad is treated like a button we convert button press bool flags into axis values 775 | if (axisName == null) 776 | { 777 | switch (controllerType) { 778 | case OuyaControllerType.Ouya: 779 | if (GetButton(10, ButtonAction.Pressed, player)) return -1f; 780 | else if (GetButton(11, ButtonAction.Pressed, player)) return 1f; 781 | break; 782 | case OuyaControllerType.PS3: 783 | #if !UNITY_EDITOR && UNITY_ANDROID 784 | if (GetButton(7, ButtonAction.Pressed, player)) return -1f; 785 | else if (GetButton(5, ButtonAction.Pressed, player)) return 1f; 786 | #elif !UNITY_EDITOR && UNITY_STANDALONE_OSX 787 | if (GetButton(7, ButtonAction.Pressed, player)) return -1f; 788 | else if (GetButton(5, ButtonAction.Pressed, player)) return 1f; 789 | #elif !UNITY_EDITOR && UNITY_STANDALONE_WIN 790 | if (GetButton(16, ButtonAction.Pressed, player)) return -1f; 791 | else if (GetButton(14, ButtonAction.Pressed, player)) return 1f; 792 | #elif UNITY_EDITOR 793 | // in the editor we have to set on which platform we are working 794 | // different editor working environments are not covered by Unity's macros 795 | if (editorWorkPlatform == EditorWorkPlatform.MacOS) 796 | { 797 | if (GetButton(7, ButtonAction.Pressed, player)) return -1f; 798 | else if (GetButton(5, ButtonAction.Pressed, player)) return 1f; 799 | } 800 | else { 801 | if (GetButton(16, ButtonAction.Pressed, player)) return -1f; 802 | else if (GetButton(14, ButtonAction.Pressed, player)) return 1f; 803 | } 804 | #endif 805 | break; 806 | #if UNITY_EDITOR || UNITY_STANDALONE_OSX 807 | case OuyaControllerType.TattieBogle: 808 | if (GetButton(7, ButtonAction.Pressed, player)) return -1f; 809 | else if (GetButton(8, ButtonAction.Pressed, player)) return 1f; 810 | break; 811 | #endif 812 | } 813 | } break; 814 | /* DY-AXIS */ 815 | case OuyaAxis.DY: axisName = playerController.map_DY; invert = playerController.invert_DY; 816 | // if the dpad is treated like a button we convert button press bool flags into axis values 817 | if (axisName == null) 818 | { 819 | switch (controllerType) { 820 | case OuyaControllerType.Ouya: 821 | if (GetButton(8, ButtonAction.Pressed, player)) return 1f; 822 | else if (GetButton(9, ButtonAction.Pressed, player)) return -1f; 823 | break; 824 | case OuyaControllerType.PS3: 825 | #if !UNITY_EDITOR && UNITY_ANDROID 826 | if (GetButton(6, ButtonAction.Pressed, player)) return -1f; 827 | else if (GetButton(4, ButtonAction.Pressed, player)) return 1f; 828 | #elif !UNITY_EDITOR && UNITY_STANDALONE_OSX 829 | if (GetButton(6, ButtonAction.Pressed, player)) return -1f; 830 | else if (GetButton(4, ButtonAction.Pressed, player)) return 1f; 831 | #elif !UNITY_EDITOR && UNITY_STANDALONE_WIN 832 | if (GetButton(15, ButtonAction.Pressed, player)) return -1f; 833 | else if (GetButton(16, ButtonAction.Pressed, player)) return 1f; 834 | #elif UNITY_EDITOR 835 | // in the editor we have to set on which platform we are working (Win or MacOS) 836 | // different editor working environments are not covered by Unity's macros 837 | if (editorWorkPlatform == EditorWorkPlatform.MacOS) 838 | { 839 | if (GetButton(6, ButtonAction.Pressed, player)) return -1f; 840 | else if (GetButton(4, ButtonAction.Pressed, player)) return 1f; 841 | } 842 | else { 843 | if (GetButton(15, ButtonAction.Pressed, player)) return -1f; 844 | else if (GetButton(16, ButtonAction.Pressed, player)) return 1f; 845 | } 846 | #endif 847 | break; 848 | #if UNITY_EDITOR || UNITY_STANDALONE_OSX 849 | case OuyaControllerType.TattieBogle: 850 | if (GetButton(5, ButtonAction.Pressed, player)) return 1f; 851 | else if (GetButton(6, ButtonAction.Pressed, player)) return -1f; 852 | break; 853 | #endif 854 | } 855 | } break; 856 | 857 | default: return 0f; 858 | } 859 | } 860 | /* FINAL SECURITY CHECK */ 861 | // we return 0 if we didn't find a valid axis 862 | if (axisName == null) return 0f; 863 | 864 | /* TRIGGER AXIS RANGE MAPPING */ 865 | if (axis == OuyaAxis.LT || axis == OuyaAxis.RT) { 866 | // some trigger axis need to be remapped inrange before we can return the Unity Input 867 | if (invert) return playerController.rangeMapTriggerAxis(-Input.GetAxisRaw(axisName), axis); 868 | else return playerController.rangeMapTriggerAxis(Input.GetAxisRaw(axisName), axis); 869 | } 870 | /* AXIS FLOAT RESULT FROM UNITY INPUT */ 871 | if (invert) return -Input.GetAxisRaw(axisName); 872 | else return Input.GetAxisRaw(axisName); 873 | } 874 | #endregion 875 | 876 | #region BUTTON ACTION ACCESS 877 | 878 | public static bool GetButton(OuyaButton button,OuyaPlayer player) { 879 | /* this serves as the OUYA eguivalent to UNITY's Input.GetButton() 880 | * returns true if the button is pressed 881 | */ 882 | // return the button state for pressed (down state) 883 | return GetButton(button, ButtonAction.Pressed, player); 884 | } 885 | 886 | public static bool GetButtonDown(OuyaButton button, OuyaPlayer player) { 887 | /* this serves as the OUYA eguivalent to UNITY's Input.GetButtonDown() 888 | * returns true for the frame the button actually goes down 889 | */ 890 | // return the button state for the frame it goes down (down event) 891 | return GetButton(button, ButtonAction.DownFrame, player); 892 | } 893 | 894 | public static bool GetButtonUp(OuyaButton button, OuyaPlayer player) { 895 | /* this serves as the OUYA eguivalent to UNITY's Input.GetButtonUp() 896 | * returns true for the frame the button actually goes up 897 | */ 898 | // return the button state for the frame it goes down (down event) 899 | return GetButton(button, ButtonAction.UpFrame, player); 900 | } 901 | #endregion 902 | 903 | /* ----------------------------------------------------------------------------------- 904 | * PRIVATE HELPER PROCEDURES 905 | */ 906 | 907 | #region PRIVATE HELPER PROCEDURES 908 | 909 | private static bool GetButton(OuyaButton button, ButtonAction buttonAction, OuyaPlayer player) { 910 | /* for retreiving joystick button values from mapped Unity Input 911 | */ 912 | 913 | /* NULL SECURITY */ 914 | // check if there is no joystick connected 915 | if (controllerNames == null) return false; 916 | 917 | // check if there are more players than joysticks 918 | // this is not really needed in CLARK – just framework coherence 919 | int playerIndex = (int) player - 1; 920 | if (playerIndex >= controllerCount) return false; 921 | 922 | // finally check if we really found a joystick for the player 923 | OuyaControllerType controllerType = controllerTypes[playerIndex]; 924 | 925 | // get the controller mapping for the player 926 | PlayerController playerController = playerControllers[playerIndex]; 927 | 928 | // secure that we have found a mapping 929 | if (playerController != null) { 930 | 931 | /* FIND THE CORRECT MAPPED BUTTON KEY */ 932 | switch (controllerType) { 933 | #if !UNITY_EDITOR && UNITY_ANDROID 934 | case OuyaControllerType.Broadcom: 935 | case OuyaControllerType.MogaPro: 936 | // this device was not tested yet 937 | // the setting were just extracted from some examples I found 938 | // please feedback if you find a way to test it 939 | switch (button) 940 | { 941 | // shoulder buttons 942 | case OuyaButton.LB: return GetButton(6, buttonAction, player); 943 | case OuyaButton.RB: return GetButton(7, buttonAction, player); 944 | 945 | // OUYA buttons 946 | case OuyaButton.O: return GetButton(0, buttonAction, player); 947 | case OuyaButton.U: return GetButton(3, buttonAction, player); 948 | case OuyaButton.Y: return GetButton(4, buttonAction, player); 949 | case OuyaButton.A: return GetButton(1, buttonAction, player); 950 | 951 | // stick buttons 952 | case OuyaButton.L3: return GetButton(13, buttonAction, player); 953 | case OuyaButton.R3: return GetButton(14, buttonAction, player); 954 | 955 | // d-pad buttons and trigger buttons 956 | // these buttons are two axis and do not give out UP or DOWN events natively 957 | // we use button state management and continuous scanning to provide these 958 | case OuyaButton.DU: return GetCachedButtonEvent(button, buttonAction, playerIndex); 959 | case OuyaButton.DD: return GetCachedButtonEvent(button, buttonAction, playerIndex); 960 | case OuyaButton.DL: return GetCachedButtonEvent(button, buttonAction, playerIndex); 961 | case OuyaButton.DR: return GetCachedButtonEvent(button, buttonAction, playerIndex); 962 | case OuyaButton.LT: return GetCachedButtonEvent(button, buttonAction, playerIndex); 963 | case OuyaButton.RT: return GetCachedButtonEvent(button, buttonAction, playerIndex); 964 | 965 | // not defined so far 966 | case OuyaButton.START: return false; 967 | case OuyaButton.SELECT: return false; 968 | case OuyaButton.SYSTEM: return false; 969 | default: return false; 970 | } 971 | 972 | case OuyaControllerType.GameStick: 973 | // tested on the real GameStick DevKit 974 | // never succeded in pairing the controller with the Ouya, Mac, Windows 975 | // strangely enough the flat d-pad has pressure sensitive axis output 976 | // triggers do not exist at all on this controller 977 | switch (button) 978 | { 979 | // OUYA buttons 980 | case OuyaButton.O: return GetButton(0, buttonAction, player); // checked 981 | case OuyaButton.U: return GetButton(3, buttonAction, player); // checked 982 | case OuyaButton.Y: return GetButton(4, buttonAction, player); // checked 983 | case OuyaButton.A: return GetButton(1, buttonAction, player); // checked 984 | 985 | // shoulder buttons 986 | case OuyaButton.LB: return GetButton(6, buttonAction, player); // checked 987 | case OuyaButton.RB: return GetButton(7, buttonAction, player); // checked 988 | 989 | // stick buttons 990 | case OuyaButton.L3: return GetButton(13, buttonAction, player); // checked 991 | case OuyaButton.R3: return GetButton(14, buttonAction, player); // checked 992 | 993 | // center buttons 994 | case OuyaButton.SELECT: return GetButton(27, buttonAction, player); // checked 995 | case OuyaButton.START: return GetButton(11, buttonAction, player); // checked 996 | 997 | // d-pad buttons 998 | // these buttons are two axis and do not give out UP or DOWN events natively 999 | // we use button state management and continuous scanning to provide these 1000 | case OuyaButton.DU: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1001 | case OuyaButton.DD: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1002 | case OuyaButton.DL: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1003 | case OuyaButton.DR: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1004 | 1005 | // the GameStick has no triggers 1006 | case OuyaButton.LT: return false; 1007 | case OuyaButton.RT: return false; 1008 | 1009 | // SYSTEN is according to GameStick documents: joystick button 20 1010 | // but this is not valid in Unity (see script reference Keycode) 1011 | case OuyaButton.SYSTEM: return false; 1012 | default: return false; 1013 | } 1014 | #endif 1015 | case OuyaControllerType.Ouya: 1016 | #if !UNITY_EDITOR && UNITY_ANDROID 1017 | // tested on the real Ouya Developers Console 1018 | // the d-pad has no pressure sensitive output although the hardware looks like it 1019 | // triggers have both: pressure sensitive axis and button event output (nice) 1020 | switch (button) 1021 | { 1022 | // shoulder buttons 1023 | case OuyaButton.LB: return GetButton(4, buttonAction, player); // checked 1024 | case OuyaButton.RB: return GetButton(5, buttonAction, player); // checked 1025 | 1026 | // OUYA buttons 1027 | case OuyaButton.O: return GetButton(0, buttonAction, player); // checked 1028 | case OuyaButton.U: return GetButton(1, buttonAction, player); // checked 1029 | case OuyaButton.Y: return GetButton(2, buttonAction, player); // checked 1030 | case OuyaButton.A: return GetButton(3, buttonAction, player); // checked 1031 | 1032 | // stick buttons 1033 | case OuyaButton.L3: return GetButton(6, buttonAction, player); // checked 1034 | case OuyaButton.R3: return GetButton(7, buttonAction, player); // checked 1035 | 1036 | // d-pad buttons 1037 | case OuyaButton.DU: return GetButton(8, buttonAction, player); // checked 1038 | case OuyaButton.DD: return GetButton(9, buttonAction, player); // checked 1039 | case OuyaButton.DL: return GetButton(10, buttonAction, player); // checked 1040 | case OuyaButton.DR: return GetButton(11, buttonAction, player); // checked 1041 | 1042 | // trigger buttons 1043 | case OuyaButton.LT: return GetButton(12, buttonAction, player); // checked 1044 | case OuyaButton.RT: return GetButton(13, buttonAction, player); // checked 1045 | 1046 | // not defined so far – or don't exist on OUYA 1047 | case OuyaButton.START: return false; 1048 | case OuyaButton.SYSTEM: return false; 1049 | case OuyaButton.SELECT: return false; 1050 | default: return false; 1051 | } 1052 | #else 1053 | // tested on Windows8 64bit (standalone player) – pairing via OS Bluetooth driver 1054 | // the d-pad has no pressure sensitive output although the hardware looks like it 1055 | // triggers have both: pressure sensitive axis and button event output 1056 | // however trigger buttons only react on full pullthrough 1057 | // therefore we prefer to use axis conversion 1058 | switch (button) 1059 | { 1060 | // shoulder buttons 1061 | case OuyaButton.LB: return GetButton(4, buttonAction, player); // checked 1062 | case OuyaButton.RB: return GetButton(5, buttonAction, player); // checked 1063 | 1064 | // OUYA buttons 1065 | case OuyaButton.O: return GetButton(0, buttonAction, player); // checked 1066 | case OuyaButton.U: return GetButton(1, buttonAction, player); // checked 1067 | case OuyaButton.Y: return GetButton(2, buttonAction, player); // checked 1068 | case OuyaButton.A: return GetButton(3, buttonAction, player); // checked 1069 | 1070 | // stick buttons 1071 | case OuyaButton.L3: return GetButton(6, buttonAction, player); // checked 1072 | case OuyaButton.R3: return GetButton(7, buttonAction, player); // checked 1073 | 1074 | // d-pad buttons 1075 | case OuyaButton.DU: return GetButton(8, buttonAction, player); // checked 1076 | case OuyaButton.DD: return GetButton(9, buttonAction, player); // checked 1077 | case OuyaButton.DL: return GetButton(10, buttonAction, player); // checked 1078 | case OuyaButton.DR: return GetButton(11, buttonAction, player); // checked 1079 | 1080 | // trigger buttons 1081 | // although button states are natively supported we use axis conversion 1082 | // this is because trigger buttons will natively only react on full pullthrough 1083 | // these buttons then are two axis and do not give out UP or DOWN events natively 1084 | // we use button state management and continuous scanning to provide these 1085 | case OuyaButton.LT: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1086 | case OuyaButton.RT: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1087 | 1088 | // not defined so far – or don't exist on OUYA 1089 | case OuyaButton.START: return false; 1090 | case OuyaButton.SYSTEM: return false; 1091 | case OuyaButton.SELECT: return false; 1092 | default: return false; 1093 | } 1094 | #endif 1095 | case OuyaControllerType.XBox360: 1096 | #if !UNITY_EDITOR && UNITY_ANDROID 1097 | // tested with the XBOX360 standard controller connected to the OUYA via USB 1098 | // hopefully wireless XBOX controllers connected via Bluetooth have the same values 1099 | // the d-pad has sensitive pressure axis output – however we won't get button events 1100 | // we need to use continuous input scanning for managing Buttonup or ButtonDown events 1101 | // the same is true for the pressure sensitive axis triggers 1102 | switch (button) 1103 | { 1104 | // OUYA buttons 1105 | case OuyaButton.O: return GetButton(0, buttonAction, player); // checked 1106 | case OuyaButton.U: return GetButton(3, buttonAction, player); // checked 1107 | case OuyaButton.Y: return GetButton(4, buttonAction, player); // checked 1108 | case OuyaButton.A: return GetButton(1, buttonAction, player); // checked 1109 | 1110 | // shoulder buttons 1111 | case OuyaButton.LB: return GetButton(6, buttonAction, player); // checked 1112 | case OuyaButton.RB: return GetButton(7, buttonAction, player); // checked 1113 | 1114 | // center buttons 1115 | case OuyaButton.START: return GetButton(11, buttonAction, player); // checked 1116 | case OuyaButton.SELECT: return GetButton(27, buttonAction, player); 1117 | 1118 | // stick buttons 1119 | case OuyaButton.L3: return GetButton(13, buttonAction, player); // checked 1120 | case OuyaButton.R3: return GetButton(14, buttonAction, player); // checked 1121 | 1122 | // d-pad buttons and trigger buttons 1123 | // these buttons are two axis and do not give out UP or DOWN events natively 1124 | // we use button state management and continuous scanning to provide these 1125 | case OuyaButton.DU: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1126 | case OuyaButton.DD: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1127 | case OuyaButton.DL: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1128 | case OuyaButton.DR: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1129 | case OuyaButton.LT: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1130 | case OuyaButton.RT: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1131 | 1132 | // not defined so far 1133 | case OuyaButton.SYSTEM: return false; 1134 | default: return false; 1135 | } 1136 | #else 1137 | switch (button) 1138 | // tested with the XBOX360 standard controller connected to a Win64 machine via USB and official driver 1139 | // hopefully wireless XBOX controllers connected via Bluetooth have the same values 1140 | // the d-pad has sensitive pressure axis output – however we won't get button events 1141 | // we need to use continuous input scanning for managing Buttonup or ButtonDown events 1142 | // the same is true for the pressure sensitive axis triggers 1143 | // this block won't treat the XBOX360 controller running on MacOSX 1144 | // on MacOSX we use the TattieBogle driver which leads to a different controller type 1145 | { 1146 | // OUYA buttons 1147 | case OuyaButton.O: return GetButton(0, buttonAction, player); // checked 1148 | case OuyaButton.U: return GetButton(2, buttonAction, player); // checked 1149 | case OuyaButton.Y: return GetButton(3, buttonAction, player); // checked 1150 | case OuyaButton.A: return GetButton(1, buttonAction, player); // checked 1151 | 1152 | // shoulder buttons 1153 | case OuyaButton.LB: return GetButton(4, buttonAction, player); // checked 1154 | case OuyaButton.RB: return GetButton(5, buttonAction, player); // checked 1155 | 1156 | // center buttons 1157 | case OuyaButton.START: return GetButton(7, buttonAction, player); // checked 1158 | case OuyaButton.SELECT: return GetButton(6, buttonAction, player); // checked 1159 | 1160 | // stick buttons 1161 | case OuyaButton.L3: return GetButton(8, buttonAction, player); // checked 1162 | case OuyaButton.R3: return GetButton(9, buttonAction, player); // checked 1163 | 1164 | // d-pad buttons and trigger buttons 1165 | // these buttons are two axis and do not give out UP or DOWN events natively 1166 | // we use button state management and continuous scanning to provide these 1167 | case OuyaButton.DU: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1168 | case OuyaButton.DD: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1169 | case OuyaButton.DL: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1170 | case OuyaButton.DR: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1171 | case OuyaButton.LT: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1172 | case OuyaButton.RT: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1173 | 1174 | // not defined so far 1175 | case OuyaButton.SYSTEM: return false; 1176 | default: return false; 1177 | } 1178 | #endif 1179 | case OuyaControllerType.PS3: 1180 | #if !UNITY_EDITOR && UNITY_ANDROID 1181 | // tested with the PS3 standard controller connected to the OUYA via Bluetooth 1182 | // pairing was achieved using a temporary USB cable connection to the OUYA 1183 | // the d-pad uses simple button events – there is no pressure sensitivity here 1184 | // triggers have both: pressure sentive axis output as well as button events 1185 | switch (button) 1186 | { 1187 | // stick buttons 1188 | case OuyaButton.L3: return GetButton(1, buttonAction, player); // checked 1189 | case OuyaButton.R3: return GetButton(2, buttonAction, player); // checked 1190 | 1191 | // center buttons 1192 | case OuyaButton.START: return GetButton(3, buttonAction, player); // checked 1193 | case OuyaButton.SELECT: return GetButton(27, buttonAction, player); // checked 1194 | 1195 | // d-pad buttons 1196 | case OuyaButton.DU: return GetButton(4, buttonAction, player); // checked 1197 | case OuyaButton.DR: return GetButton(5, buttonAction, player); // checked 1198 | case OuyaButton.DD: return GetButton(6, buttonAction, player); // checked 1199 | case OuyaButton.DL: return GetButton(7, buttonAction, player); // checked 1200 | 1201 | // trigger buttons 1202 | case OuyaButton.LT: return GetButton(8, buttonAction, player); // checked 1203 | case OuyaButton.RT: return GetButton(9, buttonAction, player); // checked 1204 | 1205 | // shoulder buttons 1206 | case OuyaButton.LB: return GetButton(10, buttonAction, player); // checked 1207 | case OuyaButton.RB: return GetButton(11, buttonAction, player); // checked 1208 | 1209 | // OUYA buttons 1210 | case OuyaButton.O: return GetButton(14, buttonAction, player); // checked 1211 | case OuyaButton.U: return GetButton(15, buttonAction, player); // checked 1212 | case OuyaButton.Y: return GetButton(12, buttonAction, player); // checked 1213 | case OuyaButton.A: return GetButton(13, buttonAction, player); // checked 1214 | 1215 | // not defined do far 1216 | case OuyaButton.SYSTEM: return false; 1217 | default: return false; 1218 | } 1219 | #elif !UNITY_EDITOR && UNITY_STANDALONE_OSX 1220 | // tested with the PS3 standard controller connected to the MacOSX via Bluetooth 1221 | // pairing was achieved using a temporary USB cable connection to the Mac 1222 | // the d-pad and triggers use simple button events – there is no pressure sensitivity here 1223 | // this is because the standard Mac connection doesn't show all the features of the controller 1224 | // we would need a designated 3rd party driver for that 1225 | switch (button) 1226 | { 1227 | // stick buttons 1228 | case OuyaButton.L3: return GetButton(1, buttonAction, player); // checked 1229 | case OuyaButton.R3: return GetButton(2, buttonAction, player); // checked 1230 | 1231 | // center buttons 1232 | case OuyaButton.START: return GetButton(3, buttonAction, player); // checked 1233 | case OuyaButton.SELECT: return GetButton(0, buttonAction, player); // checked 1234 | 1235 | // d-pad buttons 1236 | case OuyaButton.DU: return GetButton(4, buttonAction, player); // checked 1237 | case OuyaButton.DR: return GetButton(5, buttonAction, player); // checked 1238 | case OuyaButton.DD: return GetButton(6, buttonAction, player); // checked 1239 | case OuyaButton.DL: return GetButton(7, buttonAction, player); // checked 1240 | 1241 | // trigger buttons 1242 | case OuyaButton.LT: return GetButton(8, buttonAction, player); // checked 1243 | case OuyaButton.RT: return GetButton(9, buttonAction, player); // checked 1244 | 1245 | // shoulder buttons 1246 | case OuyaButton.LB: return GetButton(10, buttonAction, player); // checked 1247 | case OuyaButton.RB: return GetButton(11, buttonAction, player); // checked 1248 | 1249 | // OUYA buttons 1250 | case OuyaButton.O: return GetButton(14, buttonAction, player); // checked 1251 | case OuyaButton.U: return GetButton(15, buttonAction, player); // checked 1252 | case OuyaButton.Y: return GetButton(12, buttonAction, player); // checked 1253 | case OuyaButton.A: return GetButton(13, buttonAction, player); // checked 1254 | 1255 | // not defined do far 1256 | case OuyaButton.SYSTEM: return false; 1257 | default: return false; 1258 | } 1259 | #elif !UNITY_EDITOR && UNITY_STANDALONE_WIN 1260 | // tested with the PS3 standard controller connected to Win7 64 via USB 1261 | // custom setup was done using the most popular but crappy driver: MotionInJoy 1262 | // this needs a CUSTOM button mapping setup in the driver tools to work (see documentation) 1263 | // default sets could not be used as they do not make sense (gyro's and sticks share the same axis) 1264 | // the d-pad use simple button events – there is no pressure sensitivity here 1265 | // the triggers provide both: pressure sensitive axis output and button events 1266 | // READ THE DOCUMENTATION to make this work !!! 1267 | switch (button) 1268 | { 1269 | // OUYA buttons 1270 | case OuyaButton.O: return GetButton(2, buttonAction, player); // checked 1271 | case OuyaButton.U: return GetButton(3, buttonAction, player); // checked 1272 | case OuyaButton.Y: return GetButton(0, buttonAction, player); // checked 1273 | case OuyaButton.A: return GetButton(1, buttonAction, player); // checked 1274 | 1275 | // shoulder buttons 1276 | case OuyaButton.LB: return GetButton(4, buttonAction, player); // checked 1277 | case OuyaButton.RB: return GetButton(5, buttonAction, player); // checked 1278 | 1279 | // trigger buttons 1280 | case OuyaButton.LT: return GetButton(6, buttonAction, player); // checked 1281 | case OuyaButton.RT: return GetButton(7, buttonAction, player); // checked 1282 | 1283 | // stick buttons 1284 | case OuyaButton.L3: return GetButton(8, buttonAction, player); // checked 1285 | case OuyaButton.R3: return GetButton(9, buttonAction, player); // checked 1286 | 1287 | // center buttons 1288 | case OuyaButton.SELECT: return GetButton(10, buttonAction, player); // checked 1289 | case OuyaButton.START: return GetButton(11, buttonAction, player); // checked 1290 | case OuyaButton.SYSTEM: return GetButton(12, buttonAction, player); // checked 1291 | 1292 | // d-pad buttons 1293 | case OuyaButton.DU: return GetButton(13, buttonAction, player); // checked 1294 | case OuyaButton.DR: return GetButton(14, buttonAction, player); // checked 1295 | case OuyaButton.DD: return GetButton(15, buttonAction, player); // checked 1296 | case OuyaButton.DL: return GetButton(16, buttonAction, player); // checked 1297 | 1298 | // not defined do far 1299 | default: return false; 1300 | } 1301 | #elif UNITY_EDITOR 1302 | // the editor receives platform specific inputs which are not covered by the procompile macros 1303 | // therefore the testing developer will have to set the Editor Working Platform 1304 | // otherwise this code copies the data of the Windows and MacOSX platforms 1305 | if (editorWorkPlatform == EditorWorkPlatform.MacOS) { 1306 | // MacOSX via standard Bluetooth connection 1307 | switch (button) 1308 | { 1309 | // stick buttons 1310 | case OuyaButton.L3: return GetButton(1, buttonAction, player); // checked 1311 | case OuyaButton.R3: return GetButton(2, buttonAction, player); // checked 1312 | 1313 | // center buttons 1314 | case OuyaButton.START: return GetButton(3, buttonAction, player); // checked 1315 | case OuyaButton.SELECT: return GetButton(0, buttonAction, player); // checked 1316 | 1317 | // d-pad buttons 1318 | case OuyaButton.DU: return GetButton(4, buttonAction, player); // checked 1319 | case OuyaButton.DR: return GetButton(5, buttonAction, player); // checked 1320 | case OuyaButton.DD: return GetButton(6, buttonAction, player); // checked 1321 | case OuyaButton.DL: return GetButton(7, buttonAction, player); // checked 1322 | 1323 | // trigger buttons 1324 | case OuyaButton.LT: return GetButton(8, buttonAction, player); // checked 1325 | case OuyaButton.RT: return GetButton(9, buttonAction, player); // checked 1326 | 1327 | // shoulder buttons 1328 | case OuyaButton.LB: return GetButton(10, buttonAction, player); // checked 1329 | case OuyaButton.RB: return GetButton(11, buttonAction, player); // checked 1330 | 1331 | // OUYA buttons 1332 | case OuyaButton.O: return GetButton(14, buttonAction, player); // checked 1333 | case OuyaButton.U: return GetButton(15, buttonAction, player); // checked 1334 | case OuyaButton.Y: return GetButton(12, buttonAction, player); // checked 1335 | case OuyaButton.A: return GetButton(13, buttonAction, player); // checked 1336 | 1337 | // not defined do far 1338 | case OuyaButton.SYSTEM: return false; 1339 | default: return false; 1340 | } 1341 | } else { 1342 | // Windows7 via USB and MotionInJoy driver 1343 | switch (button) 1344 | { 1345 | // OUYA buttons 1346 | case OuyaButton.O: return GetButton(2, buttonAction, player); // checked 1347 | case OuyaButton.U: return GetButton(3, buttonAction, player); // checked 1348 | case OuyaButton.Y: return GetButton(0, buttonAction, player); // checked 1349 | case OuyaButton.A: return GetButton(1, buttonAction, player); // checked 1350 | 1351 | // shoulder buttons 1352 | case OuyaButton.LB: return GetButton(4, buttonAction, player); // checked 1353 | case OuyaButton.RB: return GetButton(5, buttonAction, player); // checked 1354 | 1355 | // trigger buttons 1356 | case OuyaButton.LT: return GetButton(6, buttonAction, player); // checked 1357 | case OuyaButton.RT: return GetButton(7, buttonAction, player); // checked 1358 | 1359 | // stick buttons 1360 | case OuyaButton.L3: return GetButton(8, buttonAction, player); // checked 1361 | case OuyaButton.R3: return GetButton(9, buttonAction, player); // checked 1362 | 1363 | // center buttons 1364 | case OuyaButton.SELECT: return GetButton(10, buttonAction, player); // checked 1365 | case OuyaButton.START: return GetButton(11, buttonAction, player); // checked 1366 | case OuyaButton.SYSTEM: return GetButton(12, buttonAction, player); // checked 1367 | 1368 | // d-pad buttons 1369 | case OuyaButton.DU: return GetButton(13, buttonAction, player); // checked 1370 | case OuyaButton.DR: return GetButton(14, buttonAction, player); // checked 1371 | case OuyaButton.DD: return GetButton(15, buttonAction, player); // checked 1372 | case OuyaButton.DL: return GetButton(16, buttonAction, player); // checked 1373 | 1374 | default: return false; 1375 | } 1376 | } 1377 | #endif 1378 | #if UNITY_EDITOR || UNITY_STANDALONE_OSX 1379 | case OuyaControllerType.TattieBogle: 1380 | // this is for the XBOX360 standard controller running on MacOSX using the TattieBogle driver 1381 | // hopefully wireless XBOX controllers connected via Bluetooth have the same values 1382 | // the d-pad has no pressure sensitivity but gives us button events 1383 | // triggers provide only pressure sensitive axis output therefore 1384 | // we need to use continuous input scanning for managing Buttonup or ButtonDown events 1385 | switch (button) 1386 | { 1387 | // shoulder buttons 1388 | case OuyaButton.LB: return GetButton(13, buttonAction, player); // checked 1389 | case OuyaButton.RB: return GetButton(14, buttonAction, player); // checked 1390 | 1391 | // OUYA buttons 1392 | case OuyaButton.O: return GetButton(16, buttonAction, player); // checked 1393 | case OuyaButton.U: return GetButton(18, buttonAction, player); // checked 1394 | case OuyaButton.Y: return GetButton(19, buttonAction, player); // checked 1395 | case OuyaButton.A: return GetButton(17, buttonAction, player); // checked 1396 | 1397 | // stick buttons 1398 | case OuyaButton.L3: return GetButton(11, buttonAction, player); // checked 1399 | case OuyaButton.R3: return GetButton(12, buttonAction, player); // checked 1400 | 1401 | // center buttons 1402 | case OuyaButton.SELECT: return GetButton(10, buttonAction, player); // checked 1403 | case OuyaButton.START: return GetButton(9, buttonAction, player); // checked 1404 | case OuyaButton.SYSTEM: return GetButton(15, buttonAction, player); // checked 1405 | 1406 | // d-pad buttons 1407 | case OuyaButton.DU: return GetButton(5, buttonAction, player); // checked 1408 | case OuyaButton.DD: return GetButton(6, buttonAction, player); // checked 1409 | case OuyaButton.DL: return GetButton(7, buttonAction, player); // checked 1410 | case OuyaButton.DR: return GetButton(8, buttonAction, player); // checked 1411 | 1412 | // trigger buttons 1413 | // the triggers are axis and do not give out UP or DOWN events natively 1414 | // we use button state management and continuous scanning to provide these 1415 | case OuyaButton.LT: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1416 | case OuyaButton.RT: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1417 | default: return false; 1418 | } 1419 | #endif 1420 | case OuyaControllerType.Unknown: 1421 | #if !UNITY_EDITOR && UNITY_ANDROID 1422 | // we hope to catch any unkown bluetooth controllers on Android here (wild card) 1423 | // there can't be any testing for that as it's just a random try 1424 | switch (button) 1425 | { 1426 | // ouya buttons 1427 | case OuyaButton.O: return GetButton(0, buttonAction, player); 1428 | case OuyaButton.U: return GetButton(3, buttonAction, player); 1429 | case OuyaButton.Y: return GetButton(4, buttonAction, player); 1430 | case OuyaButton.A: return GetButton(1, buttonAction, player); 1431 | 1432 | // shoulder buttons 1433 | case OuyaButton.LB: return GetButton(6, buttonAction, player); 1434 | case OuyaButton.RB: return GetButton(7, buttonAction, player); 1435 | 1436 | // stick buttons 1437 | case OuyaButton.L3: return GetButton(13, buttonAction, player); 1438 | case OuyaButton.R3: return GetButton(14, buttonAction, player); 1439 | 1440 | // d-pad buttons and trigger buttons 1441 | // tese buttons are axis and do not give out UP or DOWN events natively 1442 | // we use button state management and continuous scanning to provide these 1443 | case OuyaButton.DU: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1444 | case OuyaButton.DD: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1445 | case OuyaButton.DL: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1446 | case OuyaButton.DR: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1447 | case OuyaButton.LT: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1448 | case OuyaButton.RT: return GetCachedButtonEvent(button, buttonAction, playerIndex); 1449 | 1450 | // not defined so far 1451 | default: return false; 1452 | } 1453 | #endif 1454 | break; 1455 | } 1456 | } 1457 | /* SECURITY FALL THROUGH RETURN */ 1458 | return false; 1459 | } 1460 | 1461 | private static bool GetCachedButtonEvent(OuyaButton button, ButtonAction buttonAction, int playerIndex) { 1462 | /* this allows to retreive button events discovered by continuous scanning 1463 | * this will return false for ButtonUp and ButtonDown if continuousScanning is not activated 1464 | */ 1465 | // get the correct player from the index 1466 | OuyaPlayer player = (OuyaPlayer)(playerIndex + 1); 1467 | 1468 | switch (button) { 1469 | // d-pad buttons 1470 | // some d-pad buttons are two axis and do not give out UP or DOWN events natively 1471 | // we use button state management and continuous scanning to provide these 1472 | case OuyaButton.DU: 1473 | switch (buttonAction) { 1474 | case ButtonAction.DownFrame: return playerControllers[playerIndex].downEventDU; 1475 | case ButtonAction.UpFrame: return playerControllers[playerIndex].upEventDU; 1476 | default: return GetAxis(OuyaAxis.DY, player) > 0f; 1477 | } 1478 | case OuyaButton.DD: 1479 | switch (buttonAction) { 1480 | case ButtonAction.DownFrame: return playerControllers[playerIndex].downEventDD; 1481 | case ButtonAction.UpFrame: return playerControllers[playerIndex].upEventDD; 1482 | default: return GetAxis(OuyaAxis.DY, player) < 0f; 1483 | } 1484 | case OuyaButton.DL: 1485 | switch (buttonAction) { 1486 | case ButtonAction.DownFrame: return playerControllers[playerIndex].downEventDL; 1487 | case ButtonAction.UpFrame: return playerControllers[playerIndex].upEventDL; 1488 | default: return GetAxis(OuyaAxis.DX, player) < 0f; 1489 | } 1490 | case OuyaButton.DR: 1491 | switch (buttonAction) { 1492 | case ButtonAction.DownFrame: return playerControllers[playerIndex].downEventDR; 1493 | case ButtonAction.UpFrame: return playerControllers[playerIndex].upEventDR; 1494 | default: return GetAxis(OuyaAxis.DX, player) > 0f; 1495 | } 1496 | // trigger buttons 1497 | // some triggers are axis and do not give out UP or DOWN events natively 1498 | // we use button state management and continuous scanning to provide these 1499 | case OuyaButton.LT: 1500 | switch (buttonAction) { 1501 | case ButtonAction.DownFrame: return playerControllers[playerIndex].downEventLT; 1502 | case ButtonAction.UpFrame: return playerControllers[playerIndex].upEventLT; 1503 | default: return GetAxis(OuyaAxis.LT, player) > triggerThreshold; 1504 | } 1505 | case OuyaButton.RT: 1506 | switch (buttonAction) { 1507 | case ButtonAction.DownFrame: return playerControllers[playerIndex].downEventRT; 1508 | case ButtonAction.UpFrame: return playerControllers[playerIndex].upEventRT; 1509 | default: return GetAxis(OuyaAxis.RT, player) > triggerThreshold; 1510 | } 1511 | // not defined so far 1512 | default: return false; 1513 | } 1514 | } 1515 | 1516 | private static bool GetButton(int buttonNum, ButtonAction action, OuyaPlayer player) { 1517 | /* gets Unity Input from Ouya key codes derived from plaer and button number (0-19) 1518 | */ 1519 | // get the correct Ouya key code 1520 | int key = GetOuyaKeyCode(buttonNum, player); 1521 | 1522 | // return the mapped Unity input for the correct button action 1523 | switch (action) { 1524 | case ButtonAction.Pressed: return Input.GetKey((KeyCode)key); 1525 | case ButtonAction.DownFrame: return Input.GetKeyDown((KeyCode)key); 1526 | case ButtonAction.UpFrame: return Input.GetKeyUp((KeyCode)key); 1527 | default: return Input.GetKey((KeyCode)key); 1528 | } 1529 | } 1530 | 1531 | private static int GetOuyaKeyCode(int buttonNum, OuyaPlayer player) { 1532 | /* calculates the OuyKeyCodefor a given player and button number 1533 | * depends on the stability of the int chosen in OuyaKeyCodes 1534 | * the advantage is that is much faster than parsing for joystick names 1535 | */ 1536 | // the buttons numbers 0 to 19 map to player dependent joystick buttons 1537 | if (buttonNum < 20) { 1538 | // the calculations derive from the pattern of the integers assigned in OuyaKeyCodes 1539 | // joystick buttons start at 330 with player = 0 (None) 1540 | // every player has 20 keys 1541 | return (330 + buttonNum + ((int)player * 20)); 1542 | } 1543 | // othet buttons map directly to keys 1544 | else return buttonNum; 1545 | } 1546 | #endregion 1547 | 1548 | #region CONVENIENECE JOYSTICK ACCESS 1549 | 1550 | /* ----------------------------------------------------------------------------------- 1551 | * CONVINIENCE JOYSTICK ACCESS 1552 | */ 1553 | 1554 | public static void SetDeadzone(DeadzoneType type, float radius) { 1555 | /* allows to define a deadzone which will be used by convenience acces methods 1556 | * if not set otherwise the default deadzone uses 1557 | * type: circular clipped, radius: 0.25 1558 | */ 1559 | deadzoneType = type; deadzoneRadius = radius; 1560 | } 1561 | 1562 | public static void SetTriggerTreshold(float treshold) { 1563 | /* allows to adjust the trigger threshold 1564 | * this is only needed if the "Dead" values in the Input Manager Settings were set to 0. 1565 | * default is 0.1f 1566 | */ 1567 | triggerThreshold = treshold; 1568 | } 1569 | 1570 | public static Vector2 GetJoystick(OuyaJoystick joystick, OuyaPlayer player) { 1571 | /* allows to easily get the input of a joystick 1572 | * the input will already be checked by a preset deadzone 1573 | */ 1574 | switch (joystick) { 1575 | case OuyaJoystick.LeftStick: 1576 | switch (deadzoneType) { 1577 | case DeadzoneType.AxialClip: 1578 | return CheckDeadzoneAxial(GetAxis(OuyaAxis.LX, player), GetAxis(OuyaAxis.LY, player), deadzoneRadius); 1579 | case DeadzoneType.CircularClip: 1580 | return CheckDeadzoneCircular(GetAxis(OuyaAxis.LX, player), GetAxis(OuyaAxis.LY, player), deadzoneRadius); 1581 | case DeadzoneType.CircularMap: 1582 | return CheckDeadzoneRescaled(GetAxis(OuyaAxis.LX, player), GetAxis(OuyaAxis.LY, player), deadzoneRadius); 1583 | default: 1584 | return Vector2.zero; 1585 | } 1586 | case OuyaJoystick.RightStick: 1587 | switch (deadzoneType) { 1588 | case DeadzoneType.AxialClip: 1589 | return CheckDeadzoneAxial(GetAxis(OuyaAxis.RX, player), GetAxis(OuyaAxis.RY, player), deadzoneRadius); 1590 | case DeadzoneType.CircularClip: 1591 | return CheckDeadzoneCircular(GetAxis(OuyaAxis.RX, player), GetAxis(OuyaAxis.RY, player), deadzoneRadius); 1592 | case DeadzoneType.CircularMap: 1593 | return CheckDeadzoneRescaled(GetAxis(OuyaAxis.RX, player), GetAxis(OuyaAxis.RY, player), deadzoneRadius); 1594 | default: 1595 | return Vector2.zero; 1596 | } 1597 | case OuyaJoystick.DPad: 1598 | switch (deadzoneType) { 1599 | case DeadzoneType.AxialClip: 1600 | return CheckDeadzoneAxial(GetAxis(OuyaAxis.DX, player), GetAxis(OuyaAxis.DY, player), deadzoneRadius); 1601 | case DeadzoneType.CircularClip: 1602 | return CheckDeadzoneCircular(GetAxis(OuyaAxis.DX, player), GetAxis(OuyaAxis.DY, player), deadzoneRadius); 1603 | case DeadzoneType.CircularMap: 1604 | Vector2 dpadInput = CheckDeadzoneRescaled(GetAxis(OuyaAxis.DX, player), GetAxis(OuyaAxis.DY, player), deadzoneRadius); 1605 | if (dpadInput.x > 1f) dpadInput.x = 1; else if (dpadInput.x < -1) dpadInput.x = -1; 1606 | if (dpadInput.y > 1f) dpadInput.y = 1; else if (dpadInput.y < -1) dpadInput.y = -1; 1607 | return dpadInput; 1608 | default: 1609 | return Vector2.zero; 1610 | } 1611 | default: 1612 | return Vector2.zero; 1613 | } 1614 | } 1615 | 1616 | public static float GetJoystickAngle(OuyaJoystick joystick, OuyaPlayer player) { 1617 | /* returns the angle of a joystick 1618 | * This is a convenience method allowing to get the joystick input and 1619 | * calculate the angle at the same call 1620 | * angles start at the positive joystick-x-axis and then increase conterclockwise 1621 | * (x-positive-axis is 0° / y-positive axis is 90° / x-negative axis is 180° / y-negative-axis is 270°) 1622 | * no joystrick input leads to return of -1 (as 0 is a real value used for the x-positive input) 1623 | */ 1624 | return CalculateJoystickAngle(GetJoystick(joystick, player)); 1625 | } 1626 | 1627 | public static float GetTrigger(OuyaTrigger trigger, OuyaPlayer player) { 1628 | /* returns the trigger axis value after clipping by trigger deadzone 1629 | * this is needed if the "Dead" value in the Input Manager Settings were set to 0 1630 | * it allows allows to get high precision trigger input with deadzone remapping 1631 | */ 1632 | // create a field to store the results 1633 | float triggerInput; 1634 | 1635 | // get the raw trigger input 1636 | switch (trigger) { 1637 | case OuyaTrigger.Left: triggerInput = GetAxis(OuyaAxis.LT, player); break; 1638 | case OuyaTrigger.Right: triggerInput = GetAxis(OuyaAxis.RT, player); break; 1639 | default: triggerInput = 0f; break; 1640 | } 1641 | // check for deadzone clipping 1642 | if (triggerInput < triggerThreshold) return 0f; 1643 | else { 1644 | switch (deadzoneType) { 1645 | case DeadzoneType.AxialClip: return triggerInput; 1646 | case DeadzoneType.CircularClip: return triggerInput; 1647 | case DeadzoneType.CircularMap: 1648 | // remap the values to allow full range input 1649 | return (triggerInput - triggerThreshold) / (1f - triggerThreshold); 1650 | } 1651 | } 1652 | // we should never arrive here 1653 | return 0f; 1654 | } 1655 | #endregion 1656 | 1657 | #region DEADZONE HELPERS 1658 | 1659 | /* ----------------------------------------------------------------------------------- 1660 | * DEADZONE HELPERS 1661 | */ 1662 | 1663 | public static Vector2 CheckDeadzoneAxial(float xAxis, float yAxis, float deadzone) { 1664 | /* returns an input vector where each axis value inside the deadzone get clipped 1665 | * this leads to a cross shaped deadzone area 1666 | */ 1667 | // create a vector from the axis values 1668 | Vector2 stickInput = new Vector2(xAxis, yAxis); 1669 | 1670 | // clip each axis value independently if in deadzone 1671 | if(Mathf.Abs(stickInput.x) < deadzone) stickInput.x = 0.0f; 1672 | if(Mathf.Abs(stickInput.y) < deadzone) stickInput.y = 0.0f; 1673 | 1674 | return stickInput; 1675 | } 1676 | 1677 | 1678 | public static Vector2 CheckDeadzoneCircular(float xAxis, float yAxis, float deadRadius) { 1679 | /* returns an input vector where values inside the circular deadzone get clipped 1680 | * not as smooth as CheckDeadzoneRescaled() but better performance 1681 | */ 1682 | // create a vector from the axis values 1683 | Vector2 stickInput = new Vector2(xAxis, yAxis); 1684 | 1685 | // check against the square deadzone radius (no sqrt >> more performance) 1686 | if(((xAxis * xAxis) + (yAxis * yAxis)) < (deadRadius * deadRadius)) { 1687 | stickInput = Vector2.zero; 1688 | } 1689 | return stickInput; 1690 | } 1691 | 1692 | 1693 | public static Vector2 CheckDeadzoneRescaled(float xAxis, float yAxis, float deadRadius) { 1694 | /* returns an input vector with clipped circular deadzone 1695 | * values outside the deadzone will be remapped 1696 | * gives the smoothest input results (no sudden value jump on the deadzone border) 1697 | * costs a bit more performance 1698 | */ 1699 | // create a vector from the axis values 1700 | Vector2 stickInput = new Vector2(xAxis, yAxis); 1701 | // calculate its length 1702 | float inputMagnitude = stickInput.magnitude; 1703 | 1704 | // check if the input is inside the deadzone 1705 | if (inputMagnitude < deadRadius) return Vector2.zero; 1706 | else { 1707 | // rescale the clipped input vector into the non-dead zone space 1708 | stickInput *= (inputMagnitude - deadRadius) / ((1f - deadRadius) * inputMagnitude); 1709 | } 1710 | return stickInput; 1711 | } 1712 | #endregion 1713 | 1714 | #region UTILITY HELPERS 1715 | 1716 | /* ----------------------------------------------------------------------------------- 1717 | * UTILITY HELPERS 1718 | */ 1719 | 1720 | public static float CalculateJoystickAngle(Vector2 joystickInput) { 1721 | /* returns the angle of the called joystick 1722 | * angles start at the positive joystick-x-axis and then increase conterclockwise 1723 | * (x-positive-axis is 0° / y-positive axis is 90° / x-negative axis is 180° / y-negative-axis is 270°) 1724 | * no joystrick input leads to return of -1 (as 0 is a real value used for the x-positive input) 1725 | */ 1726 | // check the quadrant our joystick is in 1727 | // we need that to do the correct ploar conversion math 1728 | Quadrant quad = Quadrant.I; 1729 | if (joystickInput.x < 0 && joystickInput.y > 0) quad = Quadrant.II; 1730 | else if (joystickInput.x < 0 && joystickInput.y < 0) quad = Quadrant.III; 1731 | else if (joystickInput.x > 0 && joystickInput.y < 0) quad = Quadrant.IV; 1732 | else if (joystickInput.x == 0 && joystickInput.y > 0) quad = Quadrant.OnYPos; 1733 | else if (joystickInput.x > 0 && joystickInput.y == 0) quad = Quadrant.OnXPos; 1734 | else if (joystickInput.x == 0 && joystickInput.y < 0) quad = Quadrant.OnYNeg; 1735 | else if (joystickInput.x < 0 && joystickInput.y == 0) quad = Quadrant.OnXNeg; 1736 | else if (joystickInput.x == 0 && joystickInput.y == 0) quad = Quadrant.Zero; 1737 | 1738 | // now we can do the poloar conversion according to quadrant cases 1739 | float angle = 0f; 1740 | switch (quad) { 1741 | case Quadrant.I: 1742 | angle = Mathf.Atan2(joystickInput.y, joystickInput.x) * (180f / Mathf.PI); break; 1743 | case Quadrant.II: 1744 | angle = Mathf.Atan2(joystickInput.y, joystickInput.x) * (180f / Mathf.PI); break; 1745 | case Quadrant.III: 1746 | angle = (Mathf.Atan2(joystickInput.y, joystickInput.x) * (180f / Mathf.PI)) + 360; break; 1747 | case Quadrant.IV: 1748 | angle = (Mathf.Atan2(joystickInput.y, joystickInput.x) * (180f / Mathf.PI)) + 360; break; 1749 | case Quadrant.OnXPos: 1750 | angle = 0f; break; 1751 | case Quadrant.OnXNeg: 1752 | angle = 180f; break; 1753 | case Quadrant.OnYPos: 1754 | angle = 90f; break; 1755 | case Quadrant.OnYNeg: 1756 | angle = 270f; break; 1757 | case Quadrant.Zero: 1758 | angle = -1f; break; 1759 | } 1760 | return angle; 1761 | } 1762 | #endregion 1763 | } 1764 | 1765 | --------------------------------------------------------------------------------