87 lines
2.8 KiB
GDScript
87 lines
2.8 KiB
GDScript
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
|