Загрузка данных
extends CharacterBody3D
@export var speed = 5.0
@export var run_speed = 9.0
@export var crouch_speed = 2.5
@export var jump_velocity = 6.5
@export var mouse_sensitivity = 0.002
# Угол вертикального поворота камеры
var camera_angle = 0.0
# Высота камеры
@export var standing_camera_height = 1.3
@export var crouching_camera_height = 0.7
# Скорость перехода между стоянием и приседанием
@export var crouch_transition_speed = 8.0
@export var walk_bob_speed = 8.0
@export var walk_bob_amount = 0.04
@export var run_bob_speed = 13.0
@export var run_bob_amount = 0.07
var bob_time = 0.0
var is_runnig = false
var is_crouching = false
@onready var camera = $Camera3D
@onready var raycast = $Camera3D/RayCast3D
# Гравитация
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
func _ready():
# Захватываем мышь
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
func _input(event):
# Движение мыши
if event is InputEventMouseMotion:
if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
# Поворот персонажа влево / вправо
rotate_y(-event.relative.x * mouse_sensitivity)
# Поворот камеры вверх / вниз
var change = -event.relative.y * mouse_sensitivity
camera_angle += change
# Ограничиваем вертикальный угол камеры
camera_angle = clamp(camera_angle, -1.5, 1.5)
# Применяем вращение камеры
camera.rotation.x = camera_angle
func _physics_process(delta):
if not is_on_floor():
velocity.y -= gravity * delta
if Input.is_action_just_pressed("прыж") and is_on_floor():
velocity.y = jump_velocity
var input_dir = Input.get_vector(
"left",
"right",
"прямо",
"назат"
)
var direction = (
transform.basis * Vector3(input_dir.x, 0, input_dir.y)
).normalized()
is_crouching = Input.is_key_pressed(KEY_CTRL)
var target_height = standing_camera_height
if is_crouching:
target_height = crouching_camera_height
is_runnig = (
Input.is_key_pressed(KEY_SHIFT)
and not is_crouching
and direction.length() > 0
)
var current_speed = speed
if is_crouching:
current_speed = crouch_speed
elif is_runnig:
current_speed = run_speed
if direction.length() > 0:
velocity.x = direction.x * current_speed
velocity.z = direction.z * current_speed
else:
velocity.x = move_toward(
velocity.x,
0,
speed * 0.5 * delta
)
velocity.z = move_toward(
velocity.z,
0,
speed * 0.5 * delta
)
var horizontal_velocity = Vector2(
velocity.x,
velocity.z
)
var current_movement_speed = horizontal_velocity.length()
if is_on_floor() and current_movement_speed > 0.1:
if is_runnig:
bob_time += delta * run_bob_speed
var bob_x = cos(bob_time) * run_bob_amount
var bob_y = abs(sin(bob_time)) * run_bob_amount
camera.position.x = lerp(
camera.position.x,
bob_x,
10.0 * delta
)
camera.position.y = lerp(
camera.position.y,
target_height + bob_y,
10.0 * delta
)
else:
bob_time += delta * walk_bob_speed
var bob_x = cos(bob_time) * walk_bob_amount
var bob_y = abs(sin(bob_time)) * walk_bob_amount
camera.position.x = lerp(
camera.position.x,
bob_x,
10.0 * delta
)
camera.position.y = lerp(
camera.position.y,
target_height + bob_y,
10.0 * delta
)
else:
camera.position.x = lerp(
camera.position.x,
0.0,
10.0 * delta
)
camera.position.y = lerp(
camera.position.y,
target_height,
10.0 * delta
)
if Input.is_action_just_pressed("interact"):
if raycast.is_colliding():
var object = raycast.get_collider()
if object.has_method("interact"):
object.interact()
move_and_slide()