43 lines
1.6 KiB
GDScript
43 lines
1.6 KiB
GDScript
class_name Boat
|
|
extends FloatingBody
|
|
|
|
## All values multiplied by mass, handling the same regardless of it
|
|
@export var engine_power := 12.0 # forward thrust, m/s² at full throttle
|
|
@export var reverse_ratio := 0.4 # reverse is weaker, like a real prop
|
|
@export var throttle_response := 1.5 # how fast the engine spools up/down
|
|
@export var rudder_strength := 2.5 # turning torque at speed
|
|
@export var keel_grip := 3.0 # resistance to sliding sideways
|
|
|
|
var desired_throttle := 0.0 # move_toward target for actual throttle
|
|
var steer_input := 0.0
|
|
var throttle := 0.0
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
super(delta)
|
|
|
|
throttle = move_toward(throttle, desired_throttle, throttle_response * delta)
|
|
|
|
if submerged_ratio <= 0.0:
|
|
return # airborne: no thrust, no rudder, no keel
|
|
|
|
# boat's forward direction, flattened onto the water plane
|
|
var forward := -global_basis.z
|
|
forward.y = 0.0
|
|
forward = forward.normalized()
|
|
|
|
# --- engine ---
|
|
var power := engine_power * (reverse_ratio if throttle < 0.0 else 1.0)
|
|
apply_central_force(forward * throttle * power * mass * submerged_ratio)
|
|
|
|
# --- rudder: only bites when water flows past it ---
|
|
var forward_speed := linear_velocity.dot(forward)
|
|
var rudder_bite := clampf(forward_speed / 3.0, -1.0, 1.0)
|
|
apply_torque(Vector3.UP * steer_input * rudder_strength * rudder_bite * mass * submerged_ratio)
|
|
|
|
# --- keel: kill sideways sliding ---
|
|
var right := global_basis.x
|
|
right.y = 0.0
|
|
right = right.normalized()
|
|
var lateral_speed := linear_velocity.dot(right)
|
|
apply_central_force(-right * lateral_speed * keel_grip * mass * submerged_ratio)
|