98 lines
3.7 KiB
GDScript
98 lines
3.7 KiB
GDScript
extends CharacterBody3D
|
|
|
|
#region Variables
|
|
@export var desired_jump_height : float = 1.0
|
|
@export var gravity_multiplier : float = 2.0
|
|
@onready var collision: CollisionShape3D = $collision
|
|
@onready var neck: Node3D = $head/neck
|
|
signal fallen
|
|
signal camera_rotated(rotation_vector:Vector2)
|
|
var jump_vel: float
|
|
var _gamepad_look_vector:Vector2
|
|
var _collison_height_origin := 0.0
|
|
var input_dir:Vector2
|
|
var mult_speed:=3.75
|
|
var friction = 8
|
|
var spedometer:float
|
|
#endregion
|
|
|
|
#region Private Variables
|
|
func _ready():
|
|
#------------------------------------------------Set gravity
|
|
var default_gravity = ProjectSettings.get_setting("physics/3d/default_gravity")*gravity_multiplier
|
|
jump_vel = sqrt(2 * default_gravity * desired_jump_height)
|
|
_collison_height_origin = collision.shape.height
|
|
#------------------------------------------------Set mouse
|
|
Input.set_use_accumulated_input(false)
|
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
|
|
|
func _unhandled_input(event):
|
|
if event is InputEventMouseMotion and not GameSettings.using_gamedpad \
|
|
and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
|
_rotate_player(_gather_mouse_input(event))
|
|
|
|
func _rotate_player(motion:Vector2):
|
|
if motion == Vector2.ZERO: return
|
|
camera_rotated.emit(motion)
|
|
%head.rotate_y(motion.x)
|
|
collision.rotation.y = %head.rotation.y
|
|
neck.rotate_x(motion.y)
|
|
const mouseLimit = deg_to_rad(80)
|
|
neck.rotation.x = clamp(neck.rotation.x, -mouseLimit, mouseLimit)
|
|
|
|
func _locomotion(delta):
|
|
input_dir = Input.get_vector("left", "right", "up", "down", GameSettings.stick_deadzone)
|
|
var direction = (%head.global_basis * Vector3(input_dir.x, 0, input_dir.y))
|
|
if direction:
|
|
velocity.x = Game.lerp_toward(velocity.x, direction.x*mult_speed,friction,delta)
|
|
velocity.z = Game.lerp_toward(velocity.z, direction.z*mult_speed,friction,delta)
|
|
else:
|
|
velocity.x = Game.lerp_toward(velocity.x, 0.0, friction, delta)
|
|
velocity.z = Game.lerp_toward(velocity.z, 0.0, friction, delta)
|
|
|
|
func _gather_mouse_input(event: InputEventMouseMotion) -> Vector2:
|
|
var viewport_size = get_viewport().get_visible_rect().size
|
|
var normalized_input = event.relative / viewport_size.length()
|
|
normalized_input *= GameSettings.mouse_sens
|
|
return -normalized_input
|
|
|
|
func _gather_stick_input(delta):
|
|
var input_vector = Input.get_vector("look_right", "look_left", "look_down", "look_up",
|
|
GameSettings.stick_deadzone)
|
|
var sens_intepolated = lerpf(0.001, 0.1,GameSettings.stick_sens)
|
|
input_vector *= sens_intepolated
|
|
var smooting_interpolated = lerpf(20,2,GameSettings.stick_smoothing)
|
|
_gamepad_look_vector = Game.lerp_toward(_gamepad_look_vector, input_vector,smooting_interpolated, delta)
|
|
_rotate_player(input_vector if GameSettings.stick_smoothing == 0.0 else _gamepad_look_vector)
|
|
|
|
func _recrouch(height:float):
|
|
collision.shape.height = height
|
|
collision.position.y = collision.shape.height/2
|
|
|
|
func _process(delta: float) -> void:
|
|
if GameSettings.using_gamedpad: _gather_stick_input(delta)
|
|
func _physics_process(delta):
|
|
#------------------------------------------------Jumping
|
|
if Input.is_action_just_pressed("jump") and is_on_floor():
|
|
velocity.y += jump_vel
|
|
#------------------------------------------------Movement
|
|
_locomotion(delta)
|
|
_move_and_check(delta)
|
|
|
|
func _move_and_check(delta):
|
|
#------------------------------------------------Gravity
|
|
if is_on_floor(): friction = 8
|
|
else:
|
|
var gravity = get_gravity().y*gravity_multiplier
|
|
friction = 1
|
|
velocity.y += gravity * delta
|
|
#------------------------------------------------Speed
|
|
var real_speed = get_real_velocity()
|
|
spedometer = Vector2(real_speed.x, real_speed.z).length()
|
|
#------------------------------------------------Move and Check
|
|
var prev_fall = velocity.y
|
|
move_and_slide()
|
|
if prev_fall < -10 and velocity.y >= 0:
|
|
fallen.emit()
|
|
#endregion
|