diff --git a/levels/lobby_underground.gd b/levels/lobby_underground.gd index c816fdb..da7039e 100644 --- a/levels/lobby_underground.gd +++ b/levels/lobby_underground.gd @@ -11,4 +11,4 @@ func _process(_delta: float) -> void: if Run.bear_gate_open() or DP.b("gate_unlocked_bear"): bear_gate_open = true $AnimationPlayer.play("Gate_opening") - Controls.vibrate(0, 0.5, .5, 7) + Controls.vibrate_for(0, 0.5, .5, 7.0) diff --git a/systems/input/controls_manager.gd b/systems/input/controls_manager.gd index 66c793a..8e1a7ea 100644 --- a/systems/input/controls_manager.gd +++ b/systems/input/controls_manager.gd @@ -251,6 +251,20 @@ func vibrate(device: int, weak_magnitude: float, strong_magnitude: float, durati """ % [device, int(duration * 1000.0), weak_magnitude, strong_magnitude], true) +## Godot's own start_joy_vibration() docs warn that a single long effect is unreliable — +## "not every hardware is compatible with long effects; you may want to make a shorter +## effect and make it repeat instead." That's exactly what broke the lobby gate's 7-second +## rumble (the short 0.2 s hit-vibration works fine): this repeats vibrate() as short pulses +## to cover the same total duration instead of one long call. +func vibrate_for(device: int, weak_magnitude: float, strong_magnitude: float, + total_duration: float, pulse: float = 0.3, gap: float = 0.1) -> void: + var elapsed := 0.0 + while elapsed < total_duration: + vibrate(device, weak_magnitude, strong_magnitude, pulse) + await get_tree().create_timer(pulse + gap).timeout + elapsed += pulse + gap + + ## 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):