Skip to content

Commit 9702c42

Browse files
authored
Merge branch 'develop' into trackedposedriver-stops-tracking
2 parents 6267909 + 05635ca commit 9702c42

27 files changed

+451
-119
lines changed

Assets/Tests/InputSystem/Plugins/XInputTests.cs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,82 @@ public void Devices_SupportXboxControllerOnOSX()
150150
AssertButtonPress(gamepad, new XInputControllerOSXState().WithButton(XInputControllerOSXState.Button.Select), gamepad.selectButton);
151151
}
152152

153+
[Test]
154+
[Category("Devices")]
155+
public void Devices_SupportXboxControllerUsingOSDriverOSX()
156+
{
157+
// Native support kicks in when a device is named "Controller"
158+
// This is what macOS names the controller
159+
var device = InputSystem.AddDevice(new InputDeviceDescription
160+
{
161+
interfaceName = "HID",
162+
product = "Controller",
163+
manufacturer = "Microsoft"
164+
});
165+
166+
Assert.That(device, Is.AssignableTo<XInputController>());
167+
Assert.That(device, Is.AssignableTo<XboxGamepadMacOSNative>());
168+
var gamepad = (XboxGamepadMacOSNative)device;
169+
170+
// macOS reports the same way we do for the Y axis; e.g. up = 1, down = -1
171+
// As such, our input data from the controller doesn't need to be inverted
172+
// This is unlike our approach for the 360Controller device
173+
InputSystem.QueueStateEvent(gamepad,
174+
new XInputControllerNativeOSXState()
175+
{
176+
leftStickX = 32767,
177+
leftStickY = 32767,
178+
rightStickX = 32767,
179+
rightStickY = 32767,
180+
leftTrigger = 255,
181+
rightTrigger = 255,
182+
});
183+
184+
InputSystem.Update();
185+
186+
Assert.That(gamepad.leftStick.x.ReadValue(), Is.EqualTo(0.9999).Within(0.001));
187+
Assert.That(gamepad.leftStick.y.ReadValue(), Is.EqualTo(0.9999).Within(0.001));
188+
Assert.That(gamepad.leftStick.up.ReadValue(), Is.EqualTo(0.9999).Within(0.001));
189+
Assert.That(gamepad.leftStick.down.ReadValue(), Is.EqualTo(0.0).Within(0.001));
190+
Assert.That(gamepad.leftStick.right.ReadValue(), Is.EqualTo(0.9999).Within(0.001));
191+
Assert.That(gamepad.leftStick.left.ReadValue(), Is.EqualTo(0.0).Within(0.001));
192+
193+
Assert.That(gamepad.rightStick.x.ReadValue(), Is.EqualTo(0.9999).Within(0.001));
194+
Assert.That(gamepad.rightStick.y.ReadValue(), Is.EqualTo(0.9999).Within(0.001));
195+
Assert.That(gamepad.rightStick.up.ReadValue(), Is.EqualTo(0.9999).Within(0.001));
196+
Assert.That(gamepad.rightStick.down.ReadValue(), Is.EqualTo(0.0).Within(0.001));
197+
Assert.That(gamepad.rightStick.right.ReadValue(), Is.EqualTo(0.9999).Within(0.001));
198+
Assert.That(gamepad.rightStick.left.ReadValue(), Is.EqualTo(0.0).Within(0.001));
199+
200+
Assert.That(gamepad.leftTrigger.ReadValue(), Is.EqualTo(1));
201+
Assert.That(gamepad.rightTrigger.ReadValue(), Is.EqualTo(1));
202+
203+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.A), gamepad.aButton);
204+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.A), gamepad.buttonSouth);
205+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.B), gamepad.bButton);
206+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.B), gamepad.buttonEast);
207+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.X), gamepad.xButton);
208+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.X), gamepad.buttonWest);
209+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.Y), gamepad.yButton);
210+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.Y), gamepad.buttonNorth);
211+
212+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.DPadDown), gamepad.dpad.down);
213+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.DPadUp), gamepad.dpad.up);
214+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.DPadLeft), gamepad.dpad.left);
215+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.DPadRight), gamepad.dpad.right);
216+
217+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.LeftThumbstickPress), gamepad.leftStickButton);
218+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.RightThumbstickPress), gamepad.rightStickButton);
219+
220+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.LeftShoulder), gamepad.leftShoulder);
221+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.RightShoulder), gamepad.rightShoulder);
222+
223+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.Start), gamepad.menu);
224+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.Start), gamepad.startButton);
225+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.Select), gamepad.view);
226+
AssertButtonPress(gamepad, new XInputControllerNativeOSXState().WithButton(XInputControllerNativeOSXState.Button.Select), gamepad.selectButton);
227+
}
228+
153229
[TestCase(0x045E, 0x02E0, 16, 11)] // Xbox One Wireless Controller
154230
[TestCase(0x045E, 0x0B20, 10, 11)] // Xbox Series X|S Wireless Controller
155231
// This test is used to establish the correct button map layout based on the PID and VIDs. The usual difference

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ however, it has to be formatted properly to pass verification tests.
1010

1111
## [Unreleased] - yyyy-mm-dd
1212

13+
### Added
14+
15+
- Support for Xbox controllers over USB on macOS, using macOS's default driver. [ISXB-1548]
16+
1317
### Fixed
1418
- Fixed an analytics event being invoked twice when the Save button in the Actions view was pressed. [ISXB-1378](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1378)
1519
- Fixed an issue causing a number of errors to be displayed when using `InputTestFixture` in playmode tests with domain reloading disabled on playmode entry. [ISXB-1446](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1446)

Packages/com.unity.inputsystem/Documentation~/ActionBindings.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Each Binding has the following properties:
4848
|[`action`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_action)|The name or ID of the Action that the Binding should trigger. Note that this can be null or empty (for instance, for [composites](#composite-bindings)). Not case-sensitive.<br><br>Example: `"fire"`|
4949
|[`groups`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_groups)|A semicolon-separated list of Binding groups that the Binding belongs to. Can be null or empty. Binding groups can be anything, but are mostly used for [Control Schemes](#control-schemes). Not case-sensitive.<br><br>Example: `"Keyboard&Mouse;Gamepad"`|
5050
|[`interactions`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_interactions)|A semicolon-separated list of [Interactions](Interactions.md) to apply to input on this Binding. Note that Unity appends Interactions applied to the [Action](Actions.md) itself (if any) to this list. Not case-sensitive.<br><br>Example: `"slowTap;hold(duration=0.75)"`|
51-
|[`processors`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_processors)|A semicolon-separated list of [Processors](Processors.md) to apply to input on this Binding. Note that Unity appends Processors applied to the [Action](Actions.md) itself (if any) to this list. Not case-sensitive.<br><br>Processors on Bindings apply in addition to Processors on Controls that are providing values. For example, if you put a `stickDeadzone` Processor on a Binding and then bind it to `<Gamepad>/leftStick`, you get deadzones applied twice: once from the deadzone Processor sitting on the `leftStick` Control, and once from the Binding.<br><br>Example: `"invert;axisDeadzone(min=0.1,max=0.95)"`|
51+
|[`processors`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_processors)|A semicolon-separated list of [Processors](UsingProcessors.md) to apply to input on this Binding. Note that Unity appends Processors applied to the [Action](Actions.md) itself (if any) to this list. Not case-sensitive.<br><br>Processors on Bindings apply in addition to Processors on Controls that are providing values. For example, if you put a `stickDeadzone` Processor on a Binding and then bind it to `<Gamepad>/leftStick`, you get deadzones applied twice: once from the deadzone Processor sitting on the `leftStick` Control, and once from the Binding.<br><br>Example: `"invert;axisDeadzone(min=0.1,max=0.95)"`|
5252
|[`id`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_id)|Unique ID of the Binding. You can use it to identify the Binding when storing Binding overrides in user settings, for example.|
5353
|[`name`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_name)|Optional name of the Binding. Identifies part names inside [Composites](#composite-bindings).<br><br>Example: `"Positive"`|
5454
|[`isComposite`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_isComposite)|Whether the Binding acts as a [Composite](#composite-bindings).|
@@ -87,7 +87,7 @@ myAction.AddCompositeBinding("Axis")
8787
.With("Negative", "<Gamepad>/leftShoulder");
8888
```
8989

90-
Composites can have parameters, just like [Interactions](Interactions.md) and [Processors](Processors.md).
90+
Composites can have parameters, just like [Interactions](Interactions.md) and [Processors](UsingProcessors.md).
9191

9292
```CSharp
9393
myAction.AddCompositeBinding("Axis(whichSideWins=1)");
@@ -466,10 +466,11 @@ You can override aspects of any Binding at run-time non-destructively. Specific
466466
|Property|Override|Description|
467467
|--------|--------|-----------|
468468
|[`path`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_path)|[`overridePath`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_overridePath)|Replaces the [Control path](./Controls.md#control-paths) that determines which Control(s) are referenced in the binding. If [`overridePath`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_overridePath) is set to an empty string, the binding is effectively disabled.<br><br>Example: `"<Gamepad>/leftStick"`|
469-
|[`processors`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_processors)|[`overrideProcessors`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_overrideProcessors)|Replaces the [processors](./Processors.md) applied to the binding.<br><br>Example: `"invert,normalize(min=0,max=10)"`|
469+
|[`processors`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_processors)|[`overrideProcessors`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_overrideProcessors)|Replaces the [processors](./UsingProcessors.md) applied to the binding.<br><br>Example: `"invert,normalize(min=0,max=10)"`|
470470
|[`interactions`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_interactions)|[`overrideInteractions`](../api/UnityEngine.InputSystem.InputBinding.html#UnityEngine_InputSystem_InputBinding_overrideInteractions)|Replaces the [interactions](./Interactions.md) applied to the binding.<br><br>Example: `"tap(duration=0.5)"`|
471471

472-
>NOTE: The `override` property values will not be saved along with the Actions (for example, when calling [`InputActionAsset.ToJson()`](../api/UnityEngine.InputSystem.InputActionAsset.html#UnityEngine_InputSystem_InputActionAsset_ToJson)). See [Saving and loading rebinds](#saving-and-loading-rebinds) for details about how to persist user rebinds.
472+
> [!NOTE]
473+
> The `override` property values are not saved with the Actions, for example, when calling [`InputActionAsset.ToJson()`](../api/UnityEngine.InputSystem.InputActionAsset.html#UnityEngine_InputSystem_InputActionAsset_ToJson)). Refer to [Saving and loading rebinds](#saving-and-loading-rebinds) for details about how to persist user rebinds.
473474
474475
To set the various `override` properties, you can use the [`ApplyBindingOverride`](../api/UnityEngine.InputSystem.InputActionRebindingExtensions.html#UnityEngine_InputSystem_InputActionRebindingExtensions_ApplyBindingOverride_UnityEngine_InputSystem_InputAction_UnityEngine_InputSystem_InputBinding_) APIs.
475476

@@ -527,7 +528,7 @@ playerInput.actions["move"]
527528

528529
### Setting parameters
529530

530-
A Binding may, either through itself or through its associated Action, lead to [processor](Processors.md), [interaction](Interactions.md), and/or [composite](#composite-bindings) objects being created. These objects can have parameters you can configure through in the [Binding properties view](ActionsEditor.md#bindings) of the Action editor or through the API. This configuration will give parameters their default value.
531+
A Binding may, either through itself or through its associated Action, lead to [processor](UsingProcessors.md), [interaction](Interactions.md), and/or [composite](#composite-bindings) objects being created. These objects can have parameters you can configure through in the [Binding properties view](ActionsEditor.md#bindings) of the Action editor or through the API. This configuration will give parameters their default value.
531532

532533
```CSharp
533534
// Create an action with a "Hold" interaction on it.

Packages/com.unity.inputsystem/Documentation~/Architecture.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ The high-level Input System code interprets the data in a Device's state buffers
3131

3232
Based on the information in the layouts, the Input System then creates [Control](Controls.md) representations for each of the Device's controls, which let you read the state of each individual Control in a Device.
3333

34-
As part of the high-level system, you can also build another abstraction layer to map Input Controls to your application mechanics. Use [Actions](Actions.md) to [bind](ActionBindings.md) one or more Controls to an input in your application. The Input System then monitors these Controls for state changes, and notifies your game logic using [callbacks](RespondingToActions.md#responding-to-actions-using-callbacks). You can also specify more complex behaviors for your Actions using [Processors](Processors.md) (which perform processing on the input data before sending it to you) and [Interactions](Interactions.md) (which let you specify patterns of input on a Control to listen to, such as multi-taps).
34+
As part of the high-level system, you can also build another abstraction layer to map Input Controls to your application mechanics. Use [Actions](Actions.md) to [bind](ActionBindings.md) one or more Controls to an input in your application. The Input System then monitors these Controls for state changes, and notifies your game logic using [callbacks](RespondingToActions.md#responding-to-actions-using-callbacks). You can also specify more complex behaviors for your Actions using [Processors](UsingProcessors.md) (which perform processing on the input data before sending it to you) and [Interactions](Interactions.md) (which let you specify patterns of input on a Control to listen to, such as multi-taps).

Packages/com.unity.inputsystem/Documentation~/Controls.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ Gamepad.current.leftStick.x.ReadValue();
121121

122122
Each type of Control has a specific type of values that it returns, regardless of how many different types of formats it supports for its state. You can access this value type through the [`InputControl.valueType`](../api/UnityEngine.InputSystem.InputControl.html#UnityEngine_InputSystem_InputControl_valueType) property.
123123

124-
Reading a value from a Control might apply one or more value Processors. See documentation on [Processors](Processors.md) for more information.
124+
Reading a value from a Control might apply one or more value Processors. See documentation on [Processors](UsingProcessors.md) for more information.
125125

126126
[//]: # (#### Default State - TODO)
127127

@@ -243,7 +243,7 @@ Use [`InputControl<T>.value`](../api/UnityEngine.InputSystem.InputControl-1.html
243243

244244
### Control Value Caching
245245

246-
When the `'USE_READ_VALUE_CACHING'` internal feature flag is set, the Input System will switch to an optimized path for reading control values. This path efficiently marks controls as 'stale' when they have been actuated. Subsequent calls to [`InputControl<T>.ReadValue`](../api/UnityEngine.InputSystem.InputControl-1.html#UnityEngine_InputSystem_InputControl_1_ReadValue) will only apply control processing when there have been changes to that control or in case of control processing. Control processing in this case can mean any hard-coded processing that might exist on the control, such as with [`AxisControl`](../api/UnityEngine.InputSystem.Controls.AxisControl.html) which has built-in inversion, normalisation, scaling etc, or any processors that have been applied to the controls' [processor stack](Processors.md#processors-on-controls).
246+
When the `'USE_READ_VALUE_CACHING'` internal feature flag is set, the Input System will switch to an optimized path for reading control values. This path efficiently marks controls as 'stale' when they have been actuated. Subsequent calls to [`InputControl<T>.ReadValue`](../api/UnityEngine.InputSystem.InputControl-1.html#UnityEngine_InputSystem_InputControl_1_ReadValue) will only apply control processing when there have been changes to that control or in case of control processing. Control processing in this case can mean any hard-coded processing that might exist on the control, such as with [`AxisControl`](../api/UnityEngine.InputSystem.Controls.AxisControl.html) which has built-in inversion, normalisation, scaling etc, or any processors that have been applied to the controls' [processor stack](HowToApplyProcessors.md#processors-on-controls).
247247
> Note: Performance improvements **are currently not guaranteed** for all use cases. Even though this performance path marks controls as "stale" in an efficient way, it still has an overhead which can degrade performance in some cases.
248248
249249
A positive performance impact has been seen when:

0 commit comments

Comments
 (0)