Skip to content

Comments

Add support for joypad motion sensors#111679

Merged
Repiteo merged 1 commit intogodotengine:masterfrom
Nintorch:joypad-motion-sensors
Jan 27, 2026
Merged

Add support for joypad motion sensors#111679
Repiteo merged 1 commit intogodotengine:masterfrom
Nintorch:joypad-motion-sensors

Conversation

@Nintorch
Copy link
Contributor

@Nintorch Nintorch commented Oct 15, 2025

Closes godotengine/godot-proposals#2829
Partially supersedes #88590
Requires #111707 to be merged first

I decided to split my big SDL3 joypad features PR ( #107967 ) into several smaller PRs, starting with joypad motion sensors.

This PR adds the ability to get a joypad's motion sensors (accelerometer, gyroscope) data readings (and also a simulated gravity sensor from the accelerometer and gyroscope data). The reason the gravity sensor had to be simulated: libsdl-org/SDL#6555 (comment)
This PR also includes the methods to calibrate the motion sensors output. For calibration and gravity calculation, this PR uses https://github.com/JibbSmart/GamepadMotionHelpers

This PR was tested on Windows, but it should also work on Linux and macOS.

TODO:

  • Mention that it's recommended to disable the motion sensors if they're no longer needed because it can theoretically drain the controller's battery more quickly
  • InputEventJoypadGyroscope and InputEventJoypadAccelerometer (not sure)
  • Input.get_joy_sensor_rate()?
  • Use GamepadMotionHelpers library for calibration
  • Include the accelerometer gravity part in both calibrated and non-calibrated modes (sorry for being indecisive 😅)
  • Invert the sensors axes (see also Document mobile motion and orientation sensor axes #113635 )
  • Mark the has_joy_*, set_joy_*_enabled and is_joy_*_enabled as experimental (we may or may not need to only enable/disable the motion sensors together in the future, I think)
  • Modify the usage example to use 3D nodes
  • Accelerometer usage example (not sure it's necessary)

TODO for separate PRs:

  • Accelerometer/gyroscope events
  • Accelerometer events for Input Map (Joypad Accelerometer Up/Down/Left/Right) I got feedback for this idea from Calinou, he suggested not to include those.
  • Motion sensors tutorial for the documentation (accelerometer should also be included) ( Add joypad motion sensors tutorial godot-docs#11692 )

Test project: (EDIT: it currently uses outdated method names)
joy_motion_sensors_test.zip
You should lay the controller on your desk before running the project, and after "Calibration is done" message is printed you can pick up the controller.

@Meorge
Copy link
Contributor

Meorge commented Oct 15, 2025

I'll try to test and review this on macOS soon!

I'm not a maintainer of course, but IMO it'd make sense to include the calibration methods as well. That way, this PR can function as a sort of all-encompassing "motion control API pack", if that makes sense. (Additionally/alternatively, it could be looked at from the perspective of, without being able to calibrate the sensors, how can we be confident the functions are working correctly?)

@Nintorch Nintorch force-pushed the joypad-motion-sensors branch from 891671d to fe9c73a Compare October 16, 2025 07:02
@Nintorch Nintorch changed the title Add motion sensors feature to joypads Add support for joypads motion sensors Oct 16, 2025
@AThousandShips AThousandShips changed the title Add support for joypads motion sensors Add support for joypad motion sensors Oct 19, 2025
@Nintorch Nintorch force-pushed the joypad-motion-sensors branch from fe9c73a to bcac074 Compare October 19, 2025 13:08
@Nintorch Nintorch force-pushed the joypad-motion-sensors branch 2 times, most recently from 68d3714 to f26b181 Compare November 12, 2025 11:28
@Nintorch
Copy link
Contributor Author

Nintorch commented Nov 14, 2025

Should I try combining the calibration process methods into one Input.calibrate_joy_motion_sensors() by using a separate thread and a completion signal? I tried once, but failed. I can try again though if that means the calibration becomes more convenient :D

@Nintorch
Copy link
Contributor Author

Nintorch commented Jan 25, 2026

Tested on macOS Tahoe 26.2:

  • DualSense wireless seems great!
  • Switch Pro wireless and Joy-Cons together seem like they rotate in the opposite direction of what I'd expect

For the API, I saw that the methods for enabling the gyro/accel are named like set_joy_sensors_enabled(). IMO that name - specifically, "sensors" alone - might be a bit too generic, and something like "motion_sensors" could be better. Different joypads/controllers may have different types of sensors, including ones not specific to motion, but the method names might suggest they would be included.

Quoting an older comment, but I'm thinking about it again.
If in the future there are controllers with more sensors and if we are going to support them, maybe they also should be included in has_joy_sensors() and set_joy_sensors_enabled()?
Or maybe it's probably too early to think about though.

@Nintorch Nintorch force-pushed the joypad-motion-sensors branch from 4f3e3f5 to 5bfdd7b Compare January 25, 2026 06:37
@Meorge
Copy link
Contributor

Meorge commented Jan 25, 2026

I would personally prefer to have them separated into their own sets of functions. If other sensors were added in the future, it's very possible people would not want to have both sets of sensors enabled with all of the overhead and power consumption that would entail.

As a more concrete example, consider a sensor that detects the heart rate of the player when their fingers are resting on the joypad's triggers. This would definitely qualify as a "sensor", and so I'd expect has_joy_sensors() to return true because of it, even if this joypad didn't have motion sensors. Even if it did have motion sensors, it's very likely that I would want to enable the heart-rate sensor without enabling the motion sensor, since the latter isn't applicable to my game. As such, I think having set_joy_motion_sensors_enabled() and set_joy_hr_sensors_enabled() would be more explicit, even if they are a bit verbose.

Input.set_joy_heart_rate_sensors_enabled(0, true)
Input.set_joy_motion_sensors_enabled(0, true)

print(Input.has_joy_heart_rate_sensors_sensors(0))
print(Input.has_joy_motion_sensors(0))

The methods could take in a bitfield, like so:

Input.set_joy_sensors_enabled(0, JOY_SENSOR_HEART_RATE, true)
Input.set_joy_sensors_enabled(0, JOY_SENSOR_MOTION, false)

print(Input.has_joy_sensors(0, JOY_SENSOR_HEART_RATE))
print(Input.has_joy_sensors(0, JOY_SENSOR_MOTION))

This keeps the number of unique methods in Input lower, and I think might generally be a bit easier to extend upon with new sensors as they become available, but it does make for longer lines than having dedicated methods to interface with individual sensors.

@Nintorch Nintorch force-pushed the joypad-motion-sensors branch from 5bfdd7b to a009240 Compare January 25, 2026 07:33
@Nintorch
Copy link
Contributor Author

Done! :)
I think having motion_sensors in each method name would make them too long, so I decided to replace sensors with motion:

	Vector3 get_joy_accelerometer(int p_device) const;
	Vector3 get_joy_gravity(int p_device) const;
	Vector3 get_joy_gyroscope(int p_device) const;

	void set_joy_motion_enabled(int p_device, bool p_enable);
	bool is_joy_motion_enabled(int p_device) const;

	bool has_joy_motion(int p_device) const;
	float get_joy_motion_rate(int p_device) const;

	void start_joy_motion_calibration(int p_device);
	void stop_joy_motion_calibration(int p_device);
	void clear_joy_motion_calibration(int p_device);

	Dictionary get_joy_motion_calibration(int p_device) const;
	void set_joy_motion_calibration(int p_device, const Dictionary &p_calibration_info);

	bool is_joy_motion_calibrating(int p_device) const;
	bool is_joy_motion_calibrated(int p_device) const;

	void set_joy_motion_rate(int p_device, float p_rate);

@Nintorch Nintorch force-pushed the joypad-motion-sensors branch from a009240 to a962da6 Compare January 25, 2026 08:28
@Meorge
Copy link
Contributor

Meorge commented Jan 25, 2026

It occurred to me that joy_motion could be ambiguous, as InputEventJoypadMotion is an already-existing class that refers to joystick/analog trigger movement.

@Nintorch
Copy link
Contributor Author

Oh shucks :(
Well... Either we leave things as is, or we make the method names too long 😅
I guess we'll have to see Akien's (or other maintainers') opinion on this issue.

@Meorge
Copy link
Contributor

Meorge commented Jan 25, 2026

Yeah, I think it could be good to get some other opinions on this matter 😅 Maybe someone will have an idea for another term that could be used in place of motion.

@Nintorch
Copy link
Contributor Author

Nintorch commented Jan 25, 2026

What if we add a note to InputEventJoypadMotion that tells the user to not confuse it with joypad motion sensors if we don't end up finding better names for the methods? Something like "The purpose of this event should not be confused with joypad motion sensors. This event is used for joypad axes, not joypad accelerometer or gyroscope."
After joypad motion sensors event is added we can add "For joypad motion sensors events, see InputEventJoypadMotionSensor."

@santarl
Copy link

santarl commented Jan 25, 2026

Maybe someone will have an idea for another term that could be used in place of motion.

Perhaps something like IMU (Inertial Measurement Unit)? It avoids any overlap with joypad motion events.
e.g. set_joy_imu_enabled() etc.

just a thought :D

@Nintorch
Copy link
Contributor Author

Hm, that's a good idea, thanks!

@Nintorch
Copy link
Contributor Author

As discussed on RocketChat among several developers (Akien included), the longer and more clear method names (Input.has_joy_motion_sensors(), Input.start_joy_motion_sensors_calibration()) should be used, I will try to change the code today!

@Nintorch Nintorch force-pushed the joypad-motion-sensors branch from a962da6 to a3eb202 Compare January 26, 2026 10:50
@Repiteo Repiteo merged commit 77579f9 into godotengine:master Jan 27, 2026
20 checks passed
@Repiteo
Copy link
Contributor

Repiteo commented Jan 27, 2026

Thanks!

@RetrocadeMedia
Copy link

Does this mean that we have accelerometer and gyroscope controls in Godot 4.6 or will this be coming to the next version?

@Meorge
Copy link
Contributor

Meorge commented Jan 27, 2026

Unfortunately, I believe it is scheduled for 4.7 at this point; patch releases (like 4.6.1 will be) don't include new features, as far as I know. If this PR does come to 4.6.1, it will be a shocking surprise (albeit very welcome) for me, at least 😅

@Nintorch Nintorch deleted the joypad-motion-sensors branch January 28, 2026 05:14
@Nintorch
Copy link
Contributor Author

Joypad motion sensors are real!!!

@rempas
Copy link

rempas commented Jan 28, 2026

Joypad motion sensors are real!!!

The Gyro community is very thankful to you for your awesome work!!! Thank you so, so much!

@Nintorch
Copy link
Contributor Author

Nintorch commented Jan 28, 2026

It's been a pleasure to work on implementing these features in Godot! :D

rivie13 pushed a commit to rivie13/Phoenix-Agentic-Engine that referenced this pull request Feb 16, 2026
…sors

Add support for joypad motion sensors
@stephanbogner
Copy link

This is frickin' sick! Thanks a lot to all who contributed.

I am making simple terrain/level editor for gray boxing with similar controls to Media Molecule's Dreams, so this comes at a perfect time! Looking forward to the release!

@AL2009man
Copy link

I've modified the PR to include https://github.com/JibbSmart/GamepadMotionHelpers and I can say now I'm satisfied with the result :) Now the gravity part calculation is much more advanced than my custom implementation

EDIT: though I think the gravity vector's length should always be 9.8, not lower. Done

i'm very late to the party but congraluations on the PR Merge!

given GamepadMotionHelper includes GetPlayerSpaceGyro/GetWorldSpaceGyro, will there be plans to include Gyro Orientation (Local Space, Player Space, World Space) directly to Godot or let it be reserved for developers to integrate it themselves (since GamepadMotionHelper already provides Player/World Space, but developers will have to implement Local Space themselves)?

for reference: http://gyrowiki.jibbsmart.com/blog:player-space-gyro-and-alternatives-explained

I think this option would be more ideal for game developers who plans to implement Gyro Input as a Camera

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for controller-based motion controls (gyroscope, accelerometer, …)