First-Person/scenes/player/player.gd
2025-12-06 15:43:53 +09:00

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