extends KinematicBody const MAX_VEL = 500.0 var acceleration := Vector3(0.0, -9.81, 0.0) var velocity := Vector3(0.0, 0.0, 0.0) var move_accel = 60.0 var rotate_speed = 2.0 var drag = 0.05 # Jumping var jumping := false var on_ground := false var time_since_jump_start := 0.0 var initial_jump_burst = 10.0 var jump_exponent = 0.05 export(NodePath) var solar_system func _input(event): if event.is_action_pressed("jump") and on_ground: on_ground = false jumping = true time_since_jump_start = 0.0 elif event.is_action_released("jump"): jumping = false func apply_acceleration(acceleration): # First drag, then add the new acceleration velocity *= 1 - drag velocity += acceleration # Called every frame. 'delta' is the elapsed time since the previous frame. func _physics_process(delta): var move_velocity := Vector3.ZERO var move_acceleration := Vector3.ZERO # Movement and rotation if Input.is_action_pressed("move_up"): move_acceleration.z -= move_accel if Input.is_action_pressed("move_down"): move_acceleration.z += move_accel if Input.is_action_pressed("move_left"): rotate(transform.basis.y, delta * rotate_speed) if Input.is_action_pressed("move_right"): rotate(transform.basis.y, -delta * rotate_speed) # Make movement local move_acceleration = transform.basis * move_acceleration # Jumping and Gravity var gravity_acceleration = get_node(solar_system).get_gravitation_acceleration(transform.origin) apply_acceleration((move_acceleration + gravity_acceleration) * delta) # Handle jumping if jumping: var e_section = max(exp(log(initial_jump_burst - 1 / jump_exponent * time_since_jump_start)), 0.0000001) velocity += -gravity_acceleration.normalized() * e_section time_since_jump_start += delta # Apply movement to position # FIXME: move_and_slide might make more sense, but couldn't quite get that to work... #move_and_slide(velocity, -gravity_acceleration.normalized(), true) var collision = move_and_collide(velocity * delta) if collision and not jumping: on_ground = true # Clamp the velocity just to be save velocity.x = clamp(velocity.x, -MAX_VEL, MAX_VEL) velocity.y = clamp(velocity.y, -MAX_VEL, MAX_VEL) velocity.z = clamp(velocity.z, -MAX_VEL, MAX_VEL) # Rotate down vector to face center of gravity var down = gravity_acceleration var local_down = transform.basis * Vector3.DOWN var angle = local_down.angle_to(down) var axis = local_down.cross(down).normalized() if axis != Vector3.ZERO: # Happens if we're perfectly aligned already (local_down and down are equal) rotate(axis, angle)