Merge pull request #111679 from Nintorch/joypad-motion-sensors

Add support for joypad motion sensors
This commit is contained in:
Thaddeus Crews 2026-01-27 15:18:37 -06:00
commit 77579f93e6
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
10 changed files with 1940 additions and 0 deletions

View file

@ -38,6 +38,15 @@
Adds a new mapping entry (in SDL2 format) to the mapping database. Optionally update already connected devices.
</description>
</method>
<method name="clear_joy_motion_sensors_calibration" experimental="">
<return type="void" />
<param index="0" name="device" type="int" />
<description>
Clears the calibration information for the specified joypad's motion sensors, if it has any and if they were calibrated.
See [method start_joy_motion_sensors_calibration] for an example on how to use joypad motion sensors and calibration in your games.
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="flush_buffered_events">
<return type="void" />
<description>
@ -109,6 +118,19 @@
[b]Note:[/b] For Android, [member ProjectSettings.input_devices/sensors/enable_gyroscope] must be enabled.
</description>
</method>
<method name="get_joy_accelerometer" qualifiers="const" experimental="">
<return type="Vector3" />
<param index="0" name="device" type="int" />
<description>
Returns the acceleration, including the force of gravity, in m/s² of the joypad's accelerometer sensor, if the joypad has one and it's currently enabled. Otherwise, the method returns [constant Vector3.ZERO]. See also [method get_joy_gravity] and [method set_joy_motion_sensors_enabled].
For a joypad held in front of you, the returned axes are defined as follows:
+X ... -X: left ... right;
+Y ... -Y: bottom ... top;
+Z ... -Z: farther ... closer.
The gravity part value is measured as a vector with length of [code]9.8[/code] away from the center of the Earth, which is a negative Y value.
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="get_joy_axis" qualifiers="const">
<return type="float" />
<param index="0" name="device" type="int" />
@ -117,6 +139,19 @@
Returns the current value of the joypad axis at index [param axis].
</description>
</method>
<method name="get_joy_gravity" qualifiers="const" experimental="">
<return type="Vector3" />
<param index="0" name="device" type="int" />
<description>
Returns the gravity in m/s² of the joypad's accelerometer sensor, if the joypad has one and it's currently enabled. Otherwise, the method returns [constant Vector3.ZERO]. See also [method get_joy_accelerometer] and [method set_joy_motion_sensors_enabled].
For a joypad held in front of you, the returned axes are defined as follows:
+X ... -X: left ... right;
+Y ... -Y: bottom ... top;
+Z ... -Z: farther ... closer.
The gravity part value is measured as a vector with length of [code]9.8[/code] away from the center of the Earth, which is a negative Y value.
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="get_joy_guid" qualifiers="const">
<return type="String" />
<param index="0" name="device" type="int" />
@ -125,6 +160,20 @@
On Windows, all XInput joypad GUIDs will be overridden by Godot to [code]__XINPUT_DEVICE__[/code], because their mappings are the same.
</description>
</method>
<method name="get_joy_gyroscope" qualifiers="const" experimental="">
<return type="Vector3" />
<param index="0" name="device" type="int" />
<description>
Returns the rotation rate in rad/s around a joypad's X, Y, and Z axes of the gyroscope sensor, if the joypad has one and it's currently enabled. Otherwise, the method returns [constant Vector3.ZERO]. See also [method set_joy_motion_sensors_enabled].
The rotation is positive in the counter-clockwise direction.
For a joypad held in front of you, the returned axes are defined as follows:
X: Angular speed around the X axis (pitch);
Y: Angular speed around the Y axis (yaw);
Z: Angular speed around the Z axis (roll).
See [method start_joy_motion_sensors_calibration] for an example on how to use joypad gyroscope and gyroscope calibration in your games.
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="get_joy_info" qualifiers="const">
<return type="Dictionary" />
<param index="0" name="device" type="int" />
@ -140,6 +189,25 @@
[b]Note:[/b] The returned dictionary is always empty on Android, iOS, visionOS, and Web.
</description>
</method>
<method name="get_joy_motion_sensors_calibration" qualifiers="const" experimental="">
<return type="Dictionary" />
<param index="0" name="device" type="int" />
<description>
Returns the calibration information about the specified joypad's motion sensors in the form of a [Dictionary], if it has any and if they have been calibrated, otherwise returns an empty [Dictionary].
The dictionary contains the following fields:
[code]gyroscope_offset[/code]: average offset in gyroscope values from [constant Vector2.ZERO] in rad/s.
See [method start_joy_motion_sensors_calibration] for an example on how to use joypad motion sensors and calibration in your games.
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="get_joy_motion_sensors_rate" qualifiers="const" experimental="">
<return type="float" />
<param index="0" name="device" type="int" />
<description>
Returns the joypad's motion sensor rate in Hz, if the joypad has motion sensors and they're currently enabled. See also [method set_joy_motion_sensors_enabled].
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="get_joy_name">
<return type="String" />
<param index="0" name="device" type="int" />
@ -208,6 +276,14 @@
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="has_joy_motion_sensors" qualifiers="const" experimental="">
<return type="bool" />
<param index="0" name="device" type="int" />
<description>
Returns [code]true[/code] if the joypad has motion sensors (accelerometer and gyroscope).
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="is_action_just_pressed" qualifiers="const">
<return type="bool" />
<param index="0" name="action" type="StringName" />
@ -288,6 +364,33 @@
Returns [code]true[/code] if the system knows the specified device. This means that it sets all button and axis indices. Unknown joypads are not expected to match these constants, but you can still retrieve events from them.
</description>
</method>
<method name="is_joy_motion_sensors_calibrated" qualifiers="const" experimental="">
<return type="bool" />
<param index="0" name="device" type="int" />
<description>
Returns [code]true[/code] if the joypad's motion sensors have been calibrated.
See [method start_joy_motion_sensors_calibration] for an example on how to use joypad motion sensors and calibration in your games.
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="is_joy_motion_sensors_calibrating" qualifiers="const" experimental="">
<return type="bool" />
<param index="0" name="device" type="int" />
<description>
Returns [code]true[/code] if the joypad's motion sensors are currently being calibrated.
See [method start_joy_motion_sensors_calibration] for an example on how to use joypad motion sensors and calibration in your games.
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="is_joy_motion_sensors_enabled" qualifiers="const" experimental="">
<return type="bool" />
<param index="0" name="device" type="int" />
<description>
Returns [code]true[/code] if the requested joypad has motion sensors (accelerometer and gyroscope) and they are currently enabled. See also [method set_joy_motion_sensors_enabled] and [method has_joy_motion_sensors].
See [method start_joy_motion_sensors_calibration] for an example on how to use joypad motion sensors and calibration in your games.
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="is_key_label_pressed" qualifiers="const">
<return type="bool" />
<param index="0" name="keycode" type="int" enum="Key" />
@ -407,6 +510,27 @@
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="set_joy_motion_sensors_calibration" experimental="">
<return type="void" />
<param index="0" name="device" type="int" />
<param index="1" name="calibration_info" type="Dictionary" />
<description>
Sets the specified joypad's calibration information. See also [method get_joy_motion_sensors_calibration].
See [method start_joy_motion_sensors_calibration] for an example on how to use joypad motion sensors and calibration in your games.
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="set_joy_motion_sensors_enabled" experimental="">
<return type="void" />
<param index="0" name="device" type="int" />
<param index="1" name="enable" type="bool" />
<description>
Enables or disables the motion sensors (accelerometer and gyroscope), if available, on the specified joypad.
See [method start_joy_motion_sensors_calibration] for an example on how to use joypad motion sensors and calibration in your games.
It's recommended to disable the motion sensors when they're no longer being used, because otherwise it might drain the controller battery faster.
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="set_magnetometer">
<return type="void" />
<param index="0" name="value" type="Vector3" />
@ -424,6 +548,114 @@
[b]Note:[/b] Some 3rd party tools can contribute to the list of ignored devices. For example, [i]SteamInput[/i] creates virtual devices from physical devices for remapping purposes. To avoid handling the same input device twice, the original device is added to the ignore list.
</description>
</method>
<method name="start_joy_motion_sensors_calibration" experimental="">
<return type="void" />
<param index="0" name="device" type="int" />
<description>
Starts the process of calibrating the specified joypad's gyroscope, if it has one.
Once a joypad's gyroscope has been calibrated correctly (e.g. laying still on a table without being rotated), [method get_joy_gyroscope] will return values close or equal to [constant Vector3.ZERO] when the joypad is not being rotated.
Here's an example of how to use joypad gyroscope and gyroscope calibration in your games:
[codeblocks]
[gdscript]
const GYRO_SENSITIVITY = 10.0
func _ready():
# In this example we only use the first connected joypad (id 0).
if 0 not in Input.get_connected_joypads():
return
if not Input.has_joy_motion_sensors(0):
return
# We must enable the motion sensors before using them.
Input.set_joy_motion_sensors_enabled(0, true)
# (Tell the users here that they need to put their joypads on a flat surface and wait for confirmation.)
# Start the calibration process.
calibrate_motion()
func _process(delta):
# Only move the object if the joypad motion sensors are calibrated.
if Input.is_joy_motion_sensors_calibrated(0):
move_object(delta)
func calibrate_motion():
Input.start_joy_motion_sensors_calibration(0)
# Wait for some time
await get_tree().create_timer(1.0).timeout
Input.stop_joy_motion_sensors_calibration(0)
# The joypad is now calibrated.
func move_object(delta):
var object: Node3D = ... # Put your object here.
var gyro := Input.get_joy_gyroscope(0)
object.rotation.x -= -gyro.y * GYRO_SENSITIVITY * 0.5 * delta # Use rotation around the Y axis (yaw) here
object.rotation.y += -gyro.x * GYRO_SENSITIVITY * delta # Use rotation around the X axis (pitch) here
[/gdscript]
[csharp]
const double GYRO_SENSITIVITY = 10.0;
public override void _Ready()
{
// In this example we only use the first connected joypad (id 0).
if (!Input.GetConnectedJoypads().Has(0))
{
return;
}
if (!Input.HasJoyMotionSensors(0))
{
return;
}
// We must enable the accelerometer and the gyroscope before using them.
Input.SetJoyMotionSensorsEnabled(0, true);
// (Tell the users here that they need to put their joypads on a flat surface and wait for confirmation.)
// Start the calibration process.
CalibrateMotion();
}
public override void _Process(double delta)
{
// Only move the object if the joypad motion sensors are calibrated.
if (Input.IsJoyMotionSensorsCalibrated(0))
{
MoveObject(delta);
}
}
private void CalibrateMotion()
{
Input.StartJoyMotionSensorsCalibration(0);
// Wait for some time.
await ToSignal(GetTree().CreateTimer(1.0), "timeout");
Input.StopJoyMotionSensorsCalibration(0);
// The joypad is now calibrated.
}
private void MoveObject(double delta)
{
Node3D object = ... ; // Put your object here.
Vector3 gyro = Input.GetJoyGyroscope(0);
Vector3 rotation = object.Rotation;
rotation.X -= -gyro.Y * GYRO_SENSITIVITY * 0.5 * delta; // Use rotation around the Y axis (yaw) here
rotation.Y += -gyro.X * GYRO_SENSITIVITY * delta; // Use rotation around the X axis (pitch) here
object.Rotation = rotation;
}
[/csharp]
[/codeblocks]
[b]Note:[/b] Accelerometer sensor doesn't usually require calibration.
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="start_joy_vibration">
<return type="void" />
<param index="0" name="device" type="int" />
@ -436,6 +668,15 @@
[b]Note:[/b] For macOS, vibration is only supported in macOS 11 and later. When connected via USB, vibration is only supported for major brand controllers (except Xbox One and Xbox Series X/S controllers) due to macOS limitations.
</description>
</method>
<method name="stop_joy_motion_sensors_calibration" experimental="">
<return type="void" />
<param index="0" name="device" type="int" />
<description>
Stops the calibration process of the specified joypad's motion sensors.
See [method start_joy_motion_sensors_calibration] for an example on how to use joypad motion sensors and calibration in your games.
[b]Note:[/b] This feature is only supported on Windows, Linux, and macOS.
</description>
</method>
<method name="stop_joy_vibration">
<return type="void" />
<param index="0" name="device" type="int" />