-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[macOS/iOS] Controller motion, adaptive triggers and touchpad support. #88590
base: master
Are you sure you want to change the base?
Conversation
b2862b7
to
fe10c49
Compare
Added support for adaptive triggers as well, updated demo: joypads_atrig.zip |
fe10c49
to
1421190
Compare
1421190
to
bf9afa6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested locally (M1 Mac mini 2020 with macOS Ventura and wired DualSense), it works as expected. I can't test via Bluetooth since I'm having trouble connecting the DualSense on the Mac this way (it used to work).
Great work!
I can confirm 2-finger1 touchpad movement + button, LED color, sensors (accelerometer + gyro) and all adaptive trigger modes work as expected.
One issue I noticed is that if you set the adaptive trigger's "end" point (circled in red) to a value lower than the "begin" point, errors will be spammed in the console and the project freezes:
I suggest handling this in a more graceful way, such as clamping the "end" point value to be always at least equal to the "begin" point.
Another issue I noticed is that if you call this in _ready()
, the project freezes on startup and a message is spammed in the console:
# Leave this uninitialized.
var joy_num
func _ready():
Input.set_joy_light(joy_num, Color.CYAN)
2024-02-22 22:34:58.476 godot.macos.editor.arm64[1228:11807] -[JoypadData playerIndex]: unrecognized selector sent to instance 0x60002694c6c0
ERROR: NSException: -[JoypadData playerIndex]: unrecognized selector sent to instance 0x60002694c6c0
at: run (platform/macos/os_macos.mm:778)
This also occurs if you set the light color after waiting a single frame:
func _ready():
await get_tree().process_frame
Input.set_joy_light(0, Color.WHITE)
However, the following works – wait 2 frames and call set_joy_light
in each iteration of the loop:
func _ready():
for i in 2:
await get_tree().process_frame
Input.set_joy_light(0, Color.MAGENTA)
It seems pretty sporadic as it'll sometimes occur but not always.
set_joy_light()
behaves nicely when called in _process()
, which can be used to create animations:
var counter = 0.0
func _process(delta):
counter += delta * 6
Input.set_joy_light(joy_num, Color(0.5 + sin(counter) * 0.5, 0.5 + cos(counter) * 0.5, 0))
dualsense_led_animation.mp4
Some questions:
- Is there a way to query whether the controller supports acceleration, gyro, touchpad, LED colors and adaptive triggers so we can disable relevant UI settings when these aren't supported? While we can query based on whether the lowercased controller name contains
dualshock 4
ordualsense
, this won't work with third-party controllers that may support these features. We may need something likeDisplayServer.has_feature()
for controllers. - Should we provide calibration methods for accelerometer + gyro that automatically set the current values as an offset for future calculations? Or should this be left to the project developers? @JibbSmart might have an idea about this.
Footnotes
-
I was today years old when I learned that the DualSense touchpad supports two inputs at once. ↩
It's possible (and checked internally), but not exposed, I'll add an extra function to get it.
There's no OS calibration API, but probably can be implemented in |
What's the status of the support for these features on other platforms? We should likely aim to have at least feature parity on desktop platforms. |
I have not checked yet, our current Windows implementation is outdated (DInput/Xinput) and definitely won't have any support for this. But there's a new Windows 10+ API I'm planning to check (probably a good idea to implement it anyway). No idea about Linux (touchpad on DualSense control mouse, so there's some support). |
Full support for gyro and LED control can be implemented (perhaps adaptive triggers as well), but it'll likely require godotengine/godot-proposals#9000. Mouse control by the touchpad is done by the OS driver itself (it works regardless of the current application). |
Help with calibration would be great for developers who might otherwise shy away from attempting decent motion controls. I wouldn't be able to help directly at the moment, but my header-only library GamepadMotionHelpers can help with automatic calibration, manual calibration, gravity calculation, and world space and player space conversions, and it's all contained in one file so it's easy to include |
We probably only need the HIDAPI (subproject of SDL), not full SDL. |
It's true that it technically only needs hidapi or something like it, but SDL does some really handy stuff like converting co-ordinate spaces and units from different controllers to a common standard. This is a wheel that's tedious to reinvent, and doing so won't yield any advantages besides not having to have SDL, imo. Edit: also, using SDL means automatic support for Switch controller motion controls as well |
Adds support for DualSense / DualShock 4 touchpad and gyroscope/accelerometer and DualSense adaptive triggers. As well as LED light color control and battery state info.
Modified demo project:
joypads_atrig.zip
Add support for controller-based motion controls (gyroscope, accelerometer, …) godot-proposals#2829.