diff --git a/Packages/com.unity.inputsystem/DocCodeSamples.Tests.meta b/Packages/com.unity.inputsystem/DocCodeSamples.Tests.meta
new file mode 100644
index 0000000000..b137e3ae9b
--- /dev/null
+++ b/Packages/com.unity.inputsystem/DocCodeSamples.Tests.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c0f26b555bfc14351a9f8ec342fd6ae8
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Packages/com.unity.inputsystem/DocCodeSamples.Tests/DocCodeSamples.asmdef b/Packages/com.unity.inputsystem/DocCodeSamples.Tests/DocCodeSamples.asmdef
new file mode 100644
index 0000000000..180bbcadf0
--- /dev/null
+++ b/Packages/com.unity.inputsystem/DocCodeSamples.Tests/DocCodeSamples.asmdef
@@ -0,0 +1,16 @@
+{
+ "name": "Unity.InputSystem.DocCodeSamples",
+ "rootNamespace": "",
+ "references": [
+ "GUID:75469ad4d38634e559750d17036d5f7c"
+ ],
+ "includePlatforms": [],
+ "excludePlatforms": [],
+ "allowUnsafeCode": false,
+ "overrideReferences": true,
+ "precompiledReferences": [],
+ "autoReferenced": false,
+ "defineConstraints": [],
+ "versionDefines": [],
+ "noEngineReferences": false
+}
\ No newline at end of file
diff --git a/Packages/com.unity.inputsystem/DocCodeSamples.Tests/DocCodeSamples.asmdef.meta b/Packages/com.unity.inputsystem/DocCodeSamples.Tests/DocCodeSamples.asmdef.meta
new file mode 100644
index 0000000000..213c7c30d8
--- /dev/null
+++ b/Packages/com.unity.inputsystem/DocCodeSamples.Tests/DocCodeSamples.asmdef.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 41b01d3964f844d8b43923c18b3a9a6f
+AssemblyDefinitionImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Packages/com.unity.inputsystem/DocCodeSamples.Tests/GamepadExample.cs b/Packages/com.unity.inputsystem/DocCodeSamples.Tests/GamepadExample.cs
new file mode 100644
index 0000000000..1ba384dd31
--- /dev/null
+++ b/Packages/com.unity.inputsystem/DocCodeSamples.Tests/GamepadExample.cs
@@ -0,0 +1,53 @@
+using UnityEngine;
+using UnityEngine.InputSystem;
+
+namespace DocCodeSamples.Tests
+{
+ internal class GamepadExample : MonoBehaviour
+ {
+ void Start()
+ {
+ // Print all connected gamepads
+ Debug.Log(string.Join("\n", Gamepad.all));
+ }
+
+ void Update()
+ {
+ var gamepad = Gamepad.current;
+
+ // No gamepad connected.
+ if (gamepad == null)
+ {
+ return;
+ }
+
+ // Check if "Button North" was pressed this frame
+ if (gamepad.buttonNorth.wasPressedThisFrame)
+ {
+ Debug.Log("Button North was pressed");
+ }
+
+ // Check if the button control is being continuously actuated and read its value
+ if (gamepad.rightTrigger.IsActuated())
+ {
+ Debug.Log("Right trigger value: " + gamepad.rightTrigger.ReadValue());
+ }
+
+ // Read left stick value and perform some code based on the value
+ Vector2 move = gamepad.leftStick.ReadValue();
+ {
+ // Use the Vector2 move for the game logic here
+ }
+
+ // Creating haptic feedback while "Button South" is pressed and stopping it when released.
+ if (gamepad.buttonSouth.wasPressedThisFrame)
+ {
+ gamepad.SetMotorSpeeds(0.2f, 1.0f);
+ }
+ else if (gamepad.buttonSouth.wasReleasedThisFrame)
+ {
+ gamepad.ResetHaptics();
+ }
+ }
+ }
+}
diff --git a/Packages/com.unity.inputsystem/DocCodeSamples.Tests/GamepadExample.cs.meta b/Packages/com.unity.inputsystem/DocCodeSamples.Tests/GamepadExample.cs.meta
new file mode 100644
index 0000000000..2b7c0d0a09
--- /dev/null
+++ b/Packages/com.unity.inputsystem/DocCodeSamples.Tests/GamepadExample.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 898672c95e554f2fb492125d78b11af2
+timeCreated: 1733401360
\ No newline at end of file
diff --git a/Packages/com.unity.inputsystem/DocCodeSamples.Tests/GamepadHapticsExample.cs b/Packages/com.unity.inputsystem/DocCodeSamples.Tests/GamepadHapticsExample.cs
new file mode 100644
index 0000000000..b1c414641b
--- /dev/null
+++ b/Packages/com.unity.inputsystem/DocCodeSamples.Tests/GamepadHapticsExample.cs
@@ -0,0 +1,48 @@
+using UnityEngine;
+using UnityEngine.InputSystem;
+
+namespace DocCodeSamples.Tests
+{
+ internal class GamepadHapticsExample : MonoBehaviour
+ {
+ bool hapticsArePaused = false;
+
+ void Update()
+ {
+ var gamepad = Gamepad.current;
+
+ // No gamepad connected, no need to continue.
+ if (gamepad == null)
+ return;
+
+ float leftTrigger = gamepad.leftTrigger.ReadValue();
+ float rightTrigger = gamepad.rightTrigger.ReadValue();
+
+ // Only set motor speeds if haptics were not paused and if trigger is actuated.
+ // Both triggers must be actuated past 0.2f to start haptics.
+ if (!hapticsArePaused &&
+ (gamepad.leftTrigger.IsActuated() || gamepad.rightTrigger.IsActuated()))
+ gamepad.SetMotorSpeeds(
+ leftTrigger < 0.2f ? 0.0f : leftTrigger,
+ rightTrigger < 0.2f ? 0.0f : rightTrigger);
+
+ // Toggle haptics "playback" when "Button South" is pressed.
+ // Notice that if you release the triggers after pausing,
+ // and press the button again, haptics will resume.
+ if (gamepad.buttonSouth.wasPressedThisFrame)
+ {
+ if (hapticsArePaused)
+ gamepad.ResumeHaptics();
+ else
+ gamepad.PauseHaptics();
+
+ hapticsArePaused = !hapticsArePaused;
+ }
+
+ // Notice that if you release the triggers after pausing,
+ // and press the Start button, haptics will be reset.
+ if (gamepad.startButton.wasPressedThisFrame)
+ gamepad.ResetHaptics();
+ }
+ }
+}
diff --git a/Packages/com.unity.inputsystem/DocCodeSamples.Tests/GamepadHapticsExample.cs.meta b/Packages/com.unity.inputsystem/DocCodeSamples.Tests/GamepadHapticsExample.cs.meta
new file mode 100644
index 0000000000..42a614007b
--- /dev/null
+++ b/Packages/com.unity.inputsystem/DocCodeSamples.Tests/GamepadHapticsExample.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 3bbc200178984676a2dcb977a2fe3bae
+timeCreated: 1733400387
\ No newline at end of file
diff --git a/Packages/com.unity.inputsystem/InputSystem/Devices/Gamepad.cs b/Packages/com.unity.inputsystem/InputSystem/Devices/Gamepad.cs
index 1a6a98c1e9..3841c4d723 100644
--- a/Packages/com.unity.inputsystem/InputSystem/Devices/Gamepad.cs
+++ b/Packages/com.unity.inputsystem/InputSystem/Devices/Gamepad.cs
@@ -102,7 +102,6 @@ public struct GamepadState : IInputStateTypeInfo
///
/// Button bit mask.
///
- /// Button bit mask.
///
///
///
@@ -132,20 +131,20 @@ public struct GamepadState : IInputStateTypeInfo
public uint buttons;
///
- /// Left stick position. Each axis goes from -1 to 1 with
- /// 0 being center position.
+ /// A 2D vector representing the current position of the left stick on a gamepad.
///
- /// Left stick position.
+ /// Each axis of the 2D vector's range goes from -1 to 1. 0 represents the stick in its center position, and -1 or 1 represents the the stick pushed to its extent in each direction along the axis.
///
[InputControl(layout = "Stick", usage = "Primary2DMotion", processors = "stickDeadzone", displayName = "Left Stick", shortDisplayName = "LS")]
[FieldOffset(4)]
public Vector2 leftStick;
///
- /// Right stick position. Each axis from -1 to 1 with
- /// 0 being center position.
+ /// A 2D vector representing the current position of the right stick on a gamepad.
///
- /// Right stick position.
+ /// Each axis of the 2D vector's range goes from -1 to 1.
+ /// 0 represents the stick in its center position.
+ /// -1 or 1 represents the stick pushed to its extent in each direction along the axis.
///
[InputControl(layout = "Stick", usage = "Secondary2DMotion", processors = "stickDeadzone", displayName = "Right Stick", shortDisplayName = "RS")]
[FieldOffset(12)]
@@ -154,18 +153,22 @@ public struct GamepadState : IInputStateTypeInfo
////REVIEW: should left and right trigger get deadzones?
///
- /// Position of the left trigger. Goes from 0 (not pressed) to 1 (fully pressed).
+ /// The current position of the left trigger on a gamepad.
///
- /// Position of left trigger.
+ /// The value's range goes from 0 to 1.
+ /// 0 represents the trigger in its neutral position.
+ /// 1 represents the trigger in its fully pressed position.
///
[InputControl(layout = "Button", format = "FLT", usage = "SecondaryTrigger", displayName = "Left Trigger", shortDisplayName = "LT")]
[FieldOffset(20)]
public float leftTrigger;
///
- /// Position of the right trigger. Goes from 0 (not pressed) to 1 (fully pressed).
+ /// The current position of the right trigger on a gamepad.
///
- /// Position of right trigger.
+ /// The value's range goes from 0 to 1.
+ /// 0 represents the trigger in its neutral position.
+ /// 1 represents the trigger in its fully pressed position.
///
[InputControl(layout = "Button", format = "FLT", usage = "SecondaryTrigger", displayName = "Right Trigger", shortDisplayName = "RT")]
[FieldOffset(24)]
@@ -174,7 +177,7 @@ public struct GamepadState : IInputStateTypeInfo
///
/// State format tag for GamepadState.
///
- /// Returns "GPAD".
+ /// Holds the format tag for GamepadState ("GPAD")
public FourCC format => Format;
///
@@ -399,109 +402,96 @@ namespace UnityEngine.InputSystem
/// to be mapped correctly and consistently. If, based on the set of supported devices available
/// to the input system, this cannot be guaranteed, a given device is usually represented as a
/// generic or as just a plain instead.
- ///
+ ///
///
- ///
- /// // Show all gamepads in the system.
- /// Debug.Log(string.Join("\n", Gamepad.all));
- ///
- /// // Check whether the X button on the current gamepad is pressed.
- /// if (Gamepad.current.xButton.wasPressedThisFrame)
- /// Debug.Log("Pressed");
- ///
- /// // Rumble the left motor on the current gamepad slightly.
- /// Gamepad.current.SetMotorSpeeds(0.2f, 0.
- ///
+ ///
///
- ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
[InputControlLayout(stateType = typeof(GamepadState), isGenericTypeOfDevice = true)]
public class Gamepad : InputDevice, IDualMotorRumble
{
///
/// The left face button of the gamepad.
///
- /// Control representing the X/Square face button.
///
- /// On an Xbox controller, this is the X button and on the PS4 controller, this is the
- /// square button.
+ /// Control representing the X/Square face button.
+ /// On an Xbox controller, this is the and on the PS4 controller, this is the
+ /// .
///
- ///
- ///
public ButtonControl buttonWest { get; protected set; }
///
/// The top face button of the gamepad.
///
- /// Control representing the Y/Triangle face button.
///
- /// On an Xbox controller, this is the Y button and on the PS4 controller, this is the
- /// triangle button.
+ /// Control representing the Y/Triangle face button.
+ /// On an Xbox controller, this is the and on the PS4 controller, this is the
+ /// .
///
- ///
- ///
public ButtonControl buttonNorth { get; protected set; }
///
/// The bottom face button of the gamepad.
///
- /// Control representing the A/Cross face button.
///
- /// On an Xbox controller, this is the A button and on the PS4 controller, this is the
- /// cross button.
+ /// Control representing the A/Cross face button.
+ /// On an Xbox controller, this is the and on the PS4 controller, this is the
+ /// .
///
- ///
- ///
public ButtonControl buttonSouth { get; protected set; }
///
/// The right face button of the gamepad.
///
- /// Control representing the B/Circle face button.
///
- /// On an Xbox controller, this is the B button and on the PS4 controller, this is the
- /// circle button.
+ /// Control representing the B/Circle face button.
+ /// On an Xbox controller, this is the and on the PS4 controller, this is the
+ /// .
///
- ///
- ///
public ButtonControl buttonEast { get; protected set; }
///
/// The button that gets triggered when is pressed down.
///
- /// Control representing a click with the left stick.
+ /// Control representing a click with the left stick.
public ButtonControl leftStickButton { get; protected set; }
///
/// The button that gets triggered when is pressed down.
///
- /// Control representing a click with the right stick.
+ /// Control representing a click with the right stick.
public ButtonControl rightStickButton { get; protected set; }
///
/// The right button in the middle section of the gamepad (called "menu" on Xbox
/// controllers and "options" on PS4 controllers).
///
- /// Control representing the right button in midsection.
+ /// Control representing the right button in midsection.
public ButtonControl startButton { get; protected set; }
///
/// The left button in the middle section of the gamepad (called "view" on Xbox
/// controllers and "share" on PS4 controllers).
///
- /// Control representing the left button in midsection.
+ /// Control representing the left button in midsection.
public ButtonControl selectButton { get; protected set; }
///
/// The 4-way directional pad on the gamepad.
///
- /// Control representing the d-pad.
+ /// Control representing the d-pad.
public DpadControl dpad { get; protected set; }
///
/// The left shoulder/bumper button that sits on top of .
///
- /// Control representing the left shoulder button.
///
+ /// Control representing the left shoulder button.
/// On Xbox controllers, this is usually called "left bumper" whereas on PS4
/// controllers, this button is referred to as "L1".
///
@@ -510,8 +500,8 @@ public class Gamepad : InputDevice, IDualMotorRumble
///
/// The right shoulder/bumper button that sits on top of .
///
- /// Control representing the right shoulder button.
///
+ /// Control representing the right shoulder button.
/// On Xbox controllers, this is usually called "right bumper" whereas on PS4
/// controllers, this button is referred to as "R1".
///
@@ -520,20 +510,19 @@ public class Gamepad : InputDevice, IDualMotorRumble
///
/// The left thumbstick on the gamepad.
///
- /// Control representing the left thumbstick.
+ /// Control representing the left thumbstick.
public StickControl leftStick { get; protected set; }
///
/// The right thumbstick on the gamepad.
///
- /// Control representing the right thumbstick.
+ /// Control representing the right thumbstick.
public StickControl rightStick { get; protected set; }
///
/// The left trigger button sitting below .
///
- /// Control representing the left trigger button.
- ///
+ /// Control representing the left trigger button.
/// On PS4 controllers, this button is referred to as "L2".
///
public ButtonControl leftTrigger { get; protected set; }
@@ -541,8 +530,7 @@ public class Gamepad : InputDevice, IDualMotorRumble
///
/// The right trigger button sitting below .
///
- /// Control representing the right trigger button.
- ///
+ /// Control representing the right trigger button.
/// On PS4 controllers, this button is referred to as "R2".
///
public ButtonControl rightTrigger { get; protected set; }
@@ -550,49 +538,41 @@ public class Gamepad : InputDevice, IDualMotorRumble
///
/// Same as . Xbox-style alias.
///
- /// Same as .
public ButtonControl aButton => buttonSouth;
///
/// Same as . Xbox-style alias.
///
- /// Same as .
public ButtonControl bButton => buttonEast;
///
/// Same as Xbox-style alias.
///
- /// Same as .
public ButtonControl xButton => buttonWest;
///
/// Same as . Xbox-style alias.
///
- /// Same as .
public ButtonControl yButton => buttonNorth;
///
/// Same as . PS4-style alias.
///
- /// Same as .
public ButtonControl triangleButton => buttonNorth;
///
/// Same as . PS4-style alias.
///
- /// Same as .
public ButtonControl squareButton => buttonWest;
///
/// Same as . PS4-style alias.
///
- /// Same as .
public ButtonControl circleButton => buttonEast;
///
/// Same as . PS4-style alias.
///
- /// Same as .
public ButtonControl crossButton => buttonSouth;
///
@@ -637,28 +617,29 @@ public ButtonControl this[GamepadButton button]
///
/// When added, a device is automatically made current (see ), so
/// when connecting a gamepad, it will also become current. After that, it will only become current again
- /// when input change on non-noisy controls (see ) is received.
+ /// when input change on non-noisy controls (see ) is received. It will also
+ /// be available once is queried.
///
/// For local multiplayer scenarios (or whenever there are multiple gamepads that need to be usable
/// in a concurrent fashion), it is not recommended to rely on this property. Instead, it is recommended
/// to use or .
///
- ///
- ///
public static Gamepad current { get; private set; }
///
/// A list of gamepads currently connected to the system.
///
- /// All currently connected gamepads.
///
+ /// Returns all currently connected gamepads.
+ ///
/// Does not cause GC allocation.
///
/// Do not hold on to the value returned by this getter but rather query it whenever
/// you need it. Whenever the gamepad setup changes, the value returned by this getter
/// is invalidated.
+ ///
+ /// Alternately, for querying a single gamepad, you can use for example.
///
- ///
public new static ReadOnlyArray all => new ReadOnlyArray(s_Gamepads, 0, s_GamepadCount);
///
@@ -695,24 +676,54 @@ protected override void FinishSetup()
///
///
/// This is called automatically by the system when there is input on a gamepad.
+ ///
+ /// More remarks are available in when it comes to devices with
+ /// controls.
///
+ ///
+ ///
+ /// using System;
+ /// using UnityEngine;
+ /// using UnityEngine.InputSystem;
+ ///
+ /// public class MakeCurrentGamepadExample : MonoBehaviour
+ /// {
+ /// void Update()
+ /// {
+ /// /// Make the first Gamepad always the current one
+ /// if (Gamepad.all.Count > 0)
+ /// {
+ /// Gamepad.all[0].MakeCurrent();
+ /// }
+ /// }
+ /// }
+ ///
+ ///
public override void MakeCurrent()
{
base.MakeCurrent();
current = this;
}
+ ///
///
- /// Called when the gamepad is added to the system.
+ /// Called when a gamepad is added to the system.
///
+ ///
+ /// Override this method if you want to do additional processing when a gamepad becomes connected. After this method is called, the gamepad is automatically added to the list of gamepads.
+ ///
protected override void OnAdded()
{
ArrayHelpers.AppendWithCapacity(ref s_Gamepads, ref s_GamepadCount, this);
}
+ ///
///
/// Called when the gamepad is removed from the system.
///
+ ///
+ /// Override this method if you want to do additional processing when a gamepad becomes disconnected. After this method is called, the gamepad is automatically removed from the list of gamepads.
+ ///
protected override void OnRemoved()
{
if (current == this)
@@ -730,34 +741,61 @@ protected override void OnRemoved()
}
///
- /// Pause rumble effects on the gamepad. Resume with .
+ /// Pause rumble effects on the gamepad.
///
+ ///
+ /// It will pause rumble effects and save the current motor speeds.
+ /// Resume from those speeds with .
+ /// Some devices such as and
+ /// can also set the LED color when this method is called.
+ ///
///
+ ///
+ ///
+ ///
public virtual void PauseHaptics()
{
m_Rumble.PauseHaptics(this);
}
///
- /// Resume rumble affects on the gamepad that have been paused with .
+ /// Resume rumble effects on the gamepad.
///
+ ///
+ /// It will resume rumble effects from the previously set motor speeds, such as motor speeds saved when
+ /// calling .
+ /// Some devices such as and
+ /// can also set the LED color when this method is called.
+ ///
///
+ ///
+ ///
+ ///
public virtual void ResumeHaptics()
{
m_Rumble.ResumeHaptics(this);
}
///
- /// Reset rumble effects on the gamepad. Puts the gamepad rumble motors back into their
- /// default state.
+ /// Resets rumble effects on the gamepad by setting motor speeds to 0.
///
+ ///
+ /// Some devices such as and
+ /// can also set the LED color when this method is called.
+ ///
///
+ ///
+ ///
+ ///
public virtual void ResetHaptics()
{
m_Rumble.ResetHaptics(this);
}
///
+ ///
+ ///
+ ///
public virtual void SetMotorSpeeds(float lowFrequency, float highFrequency)
{
m_Rumble.SetMotorSpeeds(this, lowFrequency, highFrequency);
diff --git a/Packages/com.unity.inputsystem/InputSystem/Devices/Haptics/DualMotorRumble.cs b/Packages/com.unity.inputsystem/InputSystem/Devices/Haptics/DualMotorRumble.cs
index 9a4d0ddba9..c54a0f4c01 100644
--- a/Packages/com.unity.inputsystem/InputSystem/Devices/Haptics/DualMotorRumble.cs
+++ b/Packages/com.unity.inputsystem/InputSystem/Devices/Haptics/DualMotorRumble.cs
@@ -39,9 +39,13 @@ internal struct DualMotorRumble
|| !Mathf.Approximately(highFrequencyMotorSpeed, 0f);
///
- /// Reset motor speeds to zero but retain current values for
- /// and .
+ /// Stops haptics by setting motor speeds to zero.
///
+ ///
+ /// Sets both motor speeds to zero while retaining the current values for
+ /// and .
+ /// It will only send the command if is true.
+ ///
/// Device to send command to.
/// is null.
public void PauseHaptics(InputDevice device)
@@ -60,6 +64,9 @@ public void PauseHaptics(InputDevice device)
/// Resume haptics by setting motor speeds to the current values of
/// and .
///
+ ///
+ /// It will only set motor speeds if is true
+ ///
/// Device to send command to.
/// is null.
public void ResumeHaptics(InputDevice device)
@@ -74,9 +81,12 @@ public void ResumeHaptics(InputDevice device)
}
///
- /// Reset haptics by setting both and
- /// to zero.
+ /// Reset haptics by setting motor speeds to zero.
///
+ ///
+ /// Sets and to zero.
+ /// It will only set motor speeds if is true.
+ ///
/// Device to send command to.
/// is null.
public void ResetHaptics(InputDevice device)