Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extends CharacterBody3D
- const WALK_SPEED: float = 700.0
- const RUN_SPEED: float = 1500.0
- const JUMP_HEIGHT: float = 12
- const SLIDE_LENGTH: float = 7.0
- var is_jump_performed: bool = false
- var is_jump_buffered: bool = false
- var is_jump_released: bool = false
- var is_jump_first_time_released: bool = false
- var can_jump: bool = false
- var speed: float = 0.0
- var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")
- var dir_when_enter_air: Vector3 = Vector3.ZERO
- var jump_is_straight: bool = false
- var jump_is_dir: bool = false
- var is_air_move_canceled: bool = false
- var is_air_strafing_on_z: bool = false
- var is_air_strafing_on_x: bool = false
- var did_diag_air_strafe: bool = false
- var can_diag_air_strafe: bool = true
- var still_diag_air_strafing: bool = false
- var is_diag_air_canceled: bool = false
- const NORMAL_AIR_MULTIPLIER: float = 1.1
- const STRAFE_AIR_MULTIPLIER: float = 0.25
- const CANCELED_AIR_MULTIPLIER: float = -0.75
- const RELEASE_CANCELED_AIR_MULTIPLIER: float = -0.37
- var air_multiplier: float = 0.0
- var is_running: bool = false
- var is_run_active: bool = false
- var is_run_buffered: bool = false
- var is_run_jump_release_buffered: bool = false
- var is_land_slide_canceled: bool = false
- var just_landed: bool = false
- var is_on_land_already: bool = false
- var dir_when_landing: Vector3 = Vector3.ZERO
- var friction: float = 1
- var y_dir: float = 0
- var input_dir: Vector3 = Vector3.ZERO
- var move_dir: Vector3 = Vector3.ZERO
- var air_move_dir: Vector3 = Vector3.ZERO
- var move_x: float = 0.0
- var move_z: float = 0.0
- var dead: bool = false
- @onready var move_dir_pivot = $MovementDirectionPivot
- func _unhandled_input(event: InputEvent)-> void:
- if dead == false:
- if event is InputEventMouseButton:
- Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
- elif event.is_action_pressed("esc"):
- Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
- if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
- if event is InputEventMouseMotion:
- move_dir_pivot.rotate_y(-event.relative.x * 0.01)
- func _physics_process(delta):
- if is_on_floor() == false:
- y_dir -= gravity * 3 * delta
- else:
- dir_when_enter_air = Vector3.ZERO
- is_run_active = false
- y_dir = 0
- is_jump_first_time_released = false
- air_multiplier = NORMAL_AIR_MULTIPLIER
- is_air_strafing_on_z = false
- is_air_strafing_on_x = false
- is_run_jump_release_buffered = false
- did_diag_air_strafe = false
- can_diag_air_strafe = true
- is_jump_performed = false
- jump_is_straight = false
- jump_is_dir = false
- if dead == false:
- jump()
- move()
- if is_on_floor() == false:
- just_landed = true
- is_on_land_already = false
- friction = 1
- move_dir = air_move_dir * speed * delta
- velocity = move_dir_pivot.basis * move_dir
- velocity.y = y_dir
- move_and_slide()
- air_strafe_calc()
- air_cancel_calc()
- else:
- if is_on_land_already == false and just_landed == true \
- or friction > 0.0 and friction < 1.0:
- if is_land_slide_canceled == false and is_jump_performed == true:
- can_jump = false
- velocity = lerp(move_dir_pivot.basis * dir_when_landing * speed * delta, \
- move_dir_pivot.basis * Vector3(dir_when_landing.x * speed, y_dir, dir_when_landing.z * speed) * 1.2 * delta, friction)
- velocity.y = y_dir
- move_and_slide()
- is_on_land_already = true
- just_landed = false
- elif is_land_slide_canceled == true and is_jump_performed == true:
- velocity = Vector3.ZERO
- velocity.y = y_dir
- move_and_slide()
- if friction <= 0.0:
- friction = 0
- is_land_slide_canceled = false
- else:
- friction -= 0.2
- if friction <= 0.8:
- can_jump = true
- move_dir = input_dir * speed * delta
- velocity = move_dir_pivot.basis * move_dir
- velocity.y = y_dir
- move_and_slide()
- func move():
- move_x = Input.get_axis("move_left", "move_right")
- move_z = Input.get_axis("move_forwards", "move_backwards")
- input_dir = Vector3(move_x, 0, move_z)
- if input_dir != null:
- input_dir.normalized()
- if Input.is_action_pressed("run") and is_jump_first_time_released == false \
- or is_run_active == true and is_jump_first_time_released == false:
- is_running = true
- is_run_buffered = true
- speed = RUN_SPEED
- elif is_run_active == true and is_jump_first_time_released == true \
- and is_on_floor() == false or is_run_jump_release_buffered == true:
- is_running = true
- is_run_jump_release_buffered = true
- speed = RUN_SPEED * 1.1
- elif Input.is_action_pressed("run") == false and is_run_active == false:
- is_running = false
- speed = WALK_SPEED
- is_run_buffered = false
- func jump():
- if Input.is_action_just_pressed("jump") and is_on_floor() == true and can_jump == true \
- and is_jump_performed == false or is_jump_buffered == true and is_on_floor() == true:
- is_jump_performed = true
- is_run_active = is_run_buffered
- dir_when_enter_air = input_dir
- dir_when_landing = dir_when_enter_air
- is_jump_buffered = false
- is_jump_released = false
- y_dir += JUMP_HEIGHT
- if Input.is_action_just_released("jump") and is_jump_performed == true \
- and is_jump_released == false and is_on_floor() == false:
- is_jump_released = true
- is_jump_first_time_released = true
- elif Input.is_action_just_released("jump"):
- is_jump_buffered = false
- if Input.is_action_pressed("jump") and is_jump_performed == true \
- and is_jump_released == true and is_jump_buffered == false \
- and is_on_floor() == false:
- is_jump_buffered = true
- func air_cancel_calc():
- if is_jump_performed == true:
- if dir_when_enter_air == Vector3(0, 0, 0):
- jump_is_straight = true
- if jump_is_straight == false:
- if dir_when_enter_air.x != input_dir.x and input_dir.z == 0 \
- or dir_when_enter_air.z != input_dir.z and input_dir.x == 0:
- air_move_dir = dir_when_enter_air * 0.4
- if input_dir != Vector3(0, y_dir, 0):
- is_land_slide_canceled = true
- friction = 0.0
- is_air_move_canceled = true
- elif did_diag_air_strafe == true and dir_when_enter_air != input_dir:
- if input_dir.x == dir_when_enter_air.x and input_dir.z != dir_when_enter_air.z \
- and input_dir.z != -dir_when_enter_air.z and input_dir.x != -dir_when_enter_air.x \
- or input_dir.z == dir_when_enter_air.z and input_dir.x != dir_when_enter_air.x \
- and input_dir.z != -dir_when_enter_air.z and input_dir.x != -dir_when_enter_air.x:
- still_diag_air_strafing = true
- else:
- still_diag_air_strafing = false
- is_diag_air_canceled = true
- is_land_slide_canceled = true
- elif dir_when_enter_air.z == input_dir.z \
- and dir_when_enter_air.x != input_dir.x and input_dir != Vector3.ZERO \
- and is_air_move_canceled == false:
- is_air_strafing_on_z = true
- elif dir_when_enter_air.x == input_dir.x \
- and dir_when_enter_air.z != input_dir.z and input_dir != Vector3.ZERO \
- and is_air_move_canceled == false:
- is_air_strafing_on_x = true
- elif jump_is_straight == true and jump_is_dir == false:
- air_multiplier = STRAFE_AIR_MULTIPLIER
- func air_strafe_calc():
- if is_jump_performed == true:
- if is_air_strafing_on_z == true and did_diag_air_strafe == false \
- and still_diag_air_strafing == false:
- can_diag_air_strafe = false
- air_move_dir = Vector3(input_dir.x * STRAFE_AIR_MULTIPLIER, y_dir, input_dir.z * air_multiplier)
- elif is_air_strafing_on_x == true and did_diag_air_strafe == false \
- and still_diag_air_strafing == false:
- can_diag_air_strafe = false
- air_move_dir = Vector3(input_dir.x * air_multiplier, y_dir, input_dir.z * STRAFE_AIR_MULTIPLIER)
- elif is_air_strafing_on_z == false and move_x == 0 \
- and did_diag_air_strafe == false and is_diag_air_canceled == false:
- can_diag_air_strafe = false
- air_move_dir = Vector3(0, y_dir, input_dir.z * air_multiplier)
- elif is_air_strafing_on_x == false and move_z == 0 \
- and did_diag_air_strafe == false and is_diag_air_canceled == false:
- can_diag_air_strafe = false
- air_move_dir = Vector3(input_dir.x * air_multiplier, y_dir, 0)
- elif is_diag_air_canceled == true and did_diag_air_strafe == true \
- and still_diag_air_strafing == false:
- can_diag_air_strafe = false
- air_move_dir = Vector3(0, y_dir, 0)
- else:
- if can_diag_air_strafe == true or still_diag_air_strafing == true:
- did_diag_air_strafe = true
- still_diag_air_strafing = true
- air_move_dir = Vector3(dir_when_enter_air.x * air_multiplier, y_dir, dir_when_enter_air.z * air_multiplier)
- else:
- air_move_dir = input_dir * air_multiplier
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement