|
1 | 1 | #if UNITY_EDITOR || UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS || PACKAGE_DOCS_GENERATION
|
2 | 2 | using System.Runtime.InteropServices;
|
| 3 | +using UnityEngine.InputSystem.Controls; |
3 | 4 | using UnityEngine.InputSystem.DualShock;
|
4 | 5 | using UnityEngine.InputSystem.Layouts;
|
5 | 6 | using UnityEngine.InputSystem.LowLevel;
|
@@ -95,6 +96,66 @@ public iOSGameControllerState WithAxis(iOSAxis axis, float value)
|
95 | 96 | return this;
|
96 | 97 | }
|
97 | 98 | }
|
| 99 | + |
| 100 | + /// <summary> |
| 101 | + /// State for iOS Gamepads using a layout where B button is south, A is east, X is north, and Y is west |
| 102 | + /// This layout is typically seen on Nintendo gamepads, such as the Switch Pro Controller. |
| 103 | + /// </summary> |
| 104 | + [StructLayout(LayoutKind.Sequential)] |
| 105 | + internal unsafe struct iOSGameControllerStateSwappedFaceButtons : IInputStateTypeInfo |
| 106 | + { |
| 107 | + public static FourCC kFormat = new FourCC('I', 'G', 'C', ' '); |
| 108 | + public const int MaxButtons = (int)iOSButton.Select + 1; |
| 109 | + public const int MaxAxis = (int)iOSAxis.RightStickY + 1; |
| 110 | + |
| 111 | + [InputControl(name = "dpad")] |
| 112 | + [InputControl(name = "dpad/up", bit = (uint)iOSButton.DpadUp)] |
| 113 | + [InputControl(name = "dpad/right", bit = (uint)iOSButton.DpadRight)] |
| 114 | + [InputControl(name = "dpad/down", bit = (uint)iOSButton.DpadDown)] |
| 115 | + [InputControl(name = "dpad/left", bit = (uint)iOSButton.DpadLeft)] |
| 116 | + [InputControl(name = "buttonSouth", bit = (uint)iOSButton.B)] |
| 117 | + [InputControl(name = "buttonWest", bit = (uint)iOSButton.Y)] |
| 118 | + [InputControl(name = "buttonNorth", bit = (uint)iOSButton.X)] |
| 119 | + [InputControl(name = "buttonEast", bit = (uint)iOSButton.A)] |
| 120 | + [InputControl(name = "leftStickPress", bit = (uint)iOSButton.LeftStick)] |
| 121 | + [InputControl(name = "rightStickPress", bit = (uint)iOSButton.RightStick)] |
| 122 | + [InputControl(name = "leftShoulder", bit = (uint)iOSButton.LeftShoulder)] |
| 123 | + [InputControl(name = "rightShoulder", bit = (uint)iOSButton.RightShoulder)] |
| 124 | + [InputControl(name = "start", bit = (uint)iOSButton.Start)] |
| 125 | + [InputControl(name = "select", bit = (uint)iOSButton.Select)] |
| 126 | + public uint buttons; |
| 127 | + |
| 128 | + [InputControl(name = "leftTrigger", offset = sizeof(uint) + sizeof(float) * (uint)iOSButton.LeftTrigger)] |
| 129 | + [InputControl(name = "rightTrigger", offset = sizeof(uint) + sizeof(float) * (uint)iOSButton.RightTrigger)] |
| 130 | + public fixed float buttonValues[MaxButtons]; |
| 131 | + |
| 132 | + private const uint kAxisOffset = sizeof(uint) + sizeof(float) * MaxButtons; |
| 133 | + [InputControl(name = "leftStick", offset = (uint)iOSAxis.LeftStickX * sizeof(float) + kAxisOffset)] |
| 134 | + [InputControl(name = "rightStick", offset = (uint)iOSAxis.RightStickX * sizeof(float) + kAxisOffset)] |
| 135 | + public fixed float axisValues[MaxAxis]; |
| 136 | + |
| 137 | + public FourCC format => kFormat; |
| 138 | + |
| 139 | + public iOSGameControllerStateSwappedFaceButtons WithButton(iOSButton button, bool value = true, float rawValue = 1.0f) |
| 140 | + { |
| 141 | + buttonValues[(int)button] = rawValue; |
| 142 | + |
| 143 | + Debug.Assert((int)button < 32, $"Expected button < 32, so we fit into the 32 bit wide bitmask"); |
| 144 | + var bit = 1U << (int)button; |
| 145 | + if (value) |
| 146 | + buttons |= bit; |
| 147 | + else |
| 148 | + buttons &= ~bit; |
| 149 | + |
| 150 | + return this; |
| 151 | + } |
| 152 | + |
| 153 | + public iOSGameControllerStateSwappedFaceButtons WithAxis(iOSAxis axis, float value) |
| 154 | + { |
| 155 | + axisValues[(int)axis] = value; |
| 156 | + return this; |
| 157 | + } |
| 158 | + } |
98 | 159 | }
|
99 | 160 |
|
100 | 161 | namespace UnityEngine.InputSystem.iOS
|
@@ -134,5 +195,41 @@ public class DualShock4GampadiOS : DualShockGamepad
|
134 | 195 | public class DualSenseGampadiOS : DualShockGamepad
|
135 | 196 | {
|
136 | 197 | }
|
| 198 | + |
| 199 | + /// <summary> |
| 200 | + /// A Switch Pro Controller connected to an iOS device. |
| 201 | + /// If you use InputSystem.GetDevice, you must query for this class rather than Gamepad in order for aButton, bButton, yButton and xButton to be correct |
| 202 | + /// </summary> |
| 203 | + [InputControlLayout(stateType = typeof(iOSGameControllerStateSwappedFaceButtons), displayName = "iOS Switch Pro Controller Gamepad")] |
| 204 | + public class SwitchProControlleriOS : Gamepad |
| 205 | + { |
| 206 | + /// <summary> |
| 207 | + /// A Button for a Nintendo Switch Pro Controller. |
| 208 | + /// If querying via script, ensure you cast the device to SwitchProControlleriOS, rather than using the Gamepad class. |
| 209 | + /// The gamepad class will return the state of buttonSouth, whereas this class returns the state of buttonEast |
| 210 | + /// </summary> |
| 211 | + public new ButtonControl aButton => buttonEast; |
| 212 | + |
| 213 | + /// <summary> |
| 214 | + /// A Button for a Nintendo Switch Pro Controller. |
| 215 | + /// If querying via script, ensure you cast the device to SwitchProControlleriOS, rather than using the Gamepad class. |
| 216 | + /// The gamepad class will return the state of buttonEast, whereas this class returns the state of buttonSouth |
| 217 | + /// </summary> |
| 218 | + public new ButtonControl bButton => buttonSouth; |
| 219 | + |
| 220 | + /// <summary> |
| 221 | + /// A Button for a Nintendo Switch Pro Controller. |
| 222 | + /// If querying via script, ensure you cast the device to SwitchProControlleriOS, rather than using the Gamepad class. |
| 223 | + /// The gamepad class will return the state of buttonNorth, whereas this class returns the state of buttonWest |
| 224 | + /// </summary> |
| 225 | + public new ButtonControl yButton => buttonWest; |
| 226 | + |
| 227 | + /// <summary> |
| 228 | + /// A Button for a Nintendo Switch Pro Controller. |
| 229 | + /// If querying via script, ensure you cast the device to SwitchProControlleriOS, rather than using the Gamepad class. |
| 230 | + /// The gamepad class will return the state of buttonWest, whereas this class returns the state of buttonNorth |
| 231 | + /// </summary> |
| 232 | + public new ButtonControl xButton => buttonNorth; |
| 233 | + } |
137 | 234 | }
|
138 | 235 | #endif // UNITY_EDITOR || UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS
|
0 commit comments