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)