vehicle.gd 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. extends VehicleBody3D
  2. const STEER_SPEED = 1.5
  3. const STEER_LIMIT = 0.4
  4. const BRAKE_STRENGTH = 2.0
  5. @export var engine_force_value := 40.0
  6. var previous_speed := linear_velocity.length()
  7. var _steer_target := 0.0
  8. @onready var desired_engine_pitch: float = $EngineSound.pitch_scale
  9. func _physics_process(delta: float):
  10. var fwd_mps := (linear_velocity * transform.basis).x
  11. _steer_target = Input.get_axis(&"turn_right", &"turn_left")
  12. _steer_target *= STEER_LIMIT
  13. # Engine sound simulation (not realistic, as this car script has no notion of gear or engine RPM).
  14. desired_engine_pitch = 0.05 + linear_velocity.length() / (engine_force_value * 0.5)
  15. # Change pitch smoothly to avoid abrupt change on collision.
  16. $EngineSound.pitch_scale = lerpf($EngineSound.pitch_scale, desired_engine_pitch, 0.2)
  17. if abs(linear_velocity.length() - previous_speed) > 1.0:
  18. # Sudden velocity change, likely due to a collision. Play an impact sound to give audible feedback,
  19. # and vibrate for haptic feedback.
  20. $ImpactSound.play()
  21. Input.vibrate_handheld(100)
  22. for joypad in Input.get_connected_joypads():
  23. Input.start_joy_vibration(joypad, 0.0, 0.5, 0.1)
  24. # Automatically accelerate when using touch controls (reversing overrides acceleration).
  25. if DisplayServer.is_touchscreen_available() or Input.is_action_pressed(&"accelerate"):
  26. # Increase engine force at low speeds to make the initial acceleration faster.
  27. var speed := linear_velocity.length()
  28. if speed < 5.0 and not is_zero_approx(speed):
  29. engine_force = clampf(engine_force_value * 5.0 / speed, 0.0, 100.0)
  30. else:
  31. engine_force = engine_force_value
  32. if not DisplayServer.is_touchscreen_available():
  33. # Apply analog throttle factor for more subtle acceleration if not fully holding down the trigger.
  34. engine_force *= Input.get_action_strength(&"accelerate")
  35. else:
  36. engine_force = 0.0
  37. if Input.is_action_pressed(&"reverse"):
  38. # Increase engine force at low speeds to make the initial reversing faster.
  39. var speed := linear_velocity.length()
  40. if speed < 5.0 and not is_zero_approx(speed):
  41. engine_force = -clampf(engine_force_value * BRAKE_STRENGTH * 5.0 / speed, 0.0, 100.0)
  42. else:
  43. engine_force = -engine_force_value * BRAKE_STRENGTH
  44. # Apply analog brake factor for more subtle braking if not fully holding down the trigger.
  45. engine_force *= Input.get_action_strength(&"reverse")
  46. steering = move_toward(steering, _steer_target, STEER_SPEED * delta)
  47. previous_speed = linear_velocity.length()