Make gamepad vibration work on web export
Input.start_joy_vibration() is a documented engine no-op on Godot's HTML5 export (never wired to the browser side). Controls.vibrate() wraps it: native platforms go straight through as before, web drives the browser's Gamepad Haptic Actuator API directly via JavaScriptBridge. Gamepad movement/ability input already worked on desktop browsers via the standard Web Gamepad API, so only vibration needed a fix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MXBNaEBmrYDSMcv4NgUWtV
This commit is contained in:
@@ -222,6 +222,35 @@ func rigid_skin_enabled() -> bool:
|
||||
return DP.b("use_rigid_skin")
|
||||
|
||||
|
||||
## Rumble a connected gamepad, gated on the DP "gamepad_vibration" flag. Off web this is a thin
|
||||
## wrapper over Input.start_joy_vibration(); on web that call is a documented engine no-op
|
||||
## (godotengine/godot#96985 — never wired to the browser side), so there we drive the Gamepad
|
||||
## Haptic Actuator API ourselves. Safe no-op wherever it's unsupported (Safari, most Firefox
|
||||
## versions, or a controller with no rumble motors) — desktop Chromium/Edge is the target.
|
||||
func vibrate(device: int, weak_magnitude: float, strong_magnitude: float, duration: float) -> void:
|
||||
if not DP.b("gamepad_vibration"):
|
||||
return
|
||||
if not OS.has_feature("web"):
|
||||
Input.start_joy_vibration(device, weak_magnitude, strong_magnitude, duration)
|
||||
return
|
||||
JavaScriptBridge.eval("""
|
||||
(function(){
|
||||
try {
|
||||
var pads = navigator.getGamepads ? navigator.getGamepads() : [];
|
||||
var pad = pads[%d];
|
||||
var act = pad && pad.vibrationActuator;
|
||||
if (act && act.playEffect) {
|
||||
act.playEffect('dual-rumble', {
|
||||
duration: %d,
|
||||
weakMagnitude: %f,
|
||||
strongMagnitude: %f
|
||||
});
|
||||
}
|
||||
} catch (e) {}
|
||||
})();
|
||||
""" % [device, int(duration * 1000.0), weak_magnitude, strong_magnitude], true)
|
||||
|
||||
|
||||
## Returns the first keyboard event bound to an action, or null.
|
||||
func get_key_event(action: StringName) -> InputEventKey:
|
||||
for event: InputEvent in InputMap.action_get_events(action):
|
||||
|
||||
Reference in New Issue
Block a user