class_name CharacterBase3D extends CharacterBody3D @export var movement: CharacterMovementBase var speed: float = 0.0 var movement_direction: Vector3 var ground_control: float = 1.0 var air_control: float = 1.0 # If [code]true[/code], [member air_control] won't be reset to [code]1.0[/code] when touching the ground. var freeze_air_control: bool = false var last_platform_velocity := Vector3.ZERO var _was_on_floor: bool = false func move(direction: Vector3, delta: float) -> void: direction *= speed var on_floor: bool = is_on_floor() if on_floor: last_platform_velocity = get_platform_velocity() # Remove platform velocity when landing. if not _was_on_floor: velocity -= get_platform_velocity() # TODO: Test if last_platform_velocity is desired. else: direction += last_platform_velocity _was_on_floor = on_floor var acceleration: float = movement.max_acceleration if on_floor else movement.max_air_acceleration var deceleration: float = movement.max_friction if on_floor else movement.max_air_friction var turning_speed: float = movement.max_turning_speed if on_floor else movement.max_air_turning_speed var speed_change: float = acceleration if direction.is_zero_approx(): speed_change = deceleration else: var flat_velocity: Vector3 = velocity * Utils.VEC3_HOR if direction.sign() != flat_velocity.sign(): speed_change = turning_speed #DebugDraw3D.draw_arrow(global_position, global_position + direction, Color.ORANGE, 0.5, true) direction.y = velocity.y speed_change *= ground_control if on_floor else air_control if on_floor and not freeze_air_control: air_control = 1.0 velocity = velocity.move_toward(direction, speed_change * delta) #DebugDraw3D.draw_arrow(global_position, global_position + velocity, Color.BLUE, 0.5, true) #Logger.print_msg("%s Velocity: %s" %[self , velocity], 0.02) ## @tutorial: https://gmtk.itch.io/platformer-toolkit/devlog/395523/behind-the-code func apply_gravity(delta: float) -> void: var margin: float = movement.gravity_check_margin var gravity_multiplier: float = 1.0 if velocity.y < -margin: #Logger.print_msg("Falling\n%s" %velocity.y, 0.02) gravity_multiplier = movement.fall_gravity_multiplier elif velocity.y > margin: #Logger.print_msg("Rising\n%s" %velocity.y, 0.02) gravity_multiplier = movement.rise_gravity_multiplier else: #Logger.print_msg("Peaking\n%s" %velocity.y, 0.02) gravity_multiplier = movement.peak_gravity_multiplier velocity.y -= (movement.get_gravity() * gravity_multiplier) * delta ## @tutorial: https://gmtk.itch.io/platformer-toolkit/devlog/395523/behind-the-code func jump() -> void: var jump_strength: float = sqrt(-2.0 * -movement.get_gravity() * movement.jump_height) if velocity.y > 0.0: jump_strength = maxf(jump_strength - velocity.y, 0.0) elif velocity.y < 0.0: jump_strength += absf(velocity.y) velocity.y += jump_strength