Загрузка данных


extends CharacterBody3D

@export_category("Movement Properties")
@export var SPEED : float = 12.0
@export var JUMP_VELOCITY : float = 14.0
@export var DASH_SPEED : float = 30.0
@export var DASH_DURATION : float = 0.2

@export_category("Camera Settings")
@export var MOUSE_SENSITIVITY : float = 0.003

# Получаем ссылки на узлы
@onready var camera_pivot: Node3D = $CameraPivot
@onready var sprite: Sprite3D = $Sprite3D

# Гравитация из настроек проекта
var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity") * 2.0

# Переменные состояния рывка
var is_dashing: bool = false
var dash_timer: float = 0.0
var dash_direction: Vector3 = Vector3.ZERO

func _ready() -> void:
	# Захватываем курсор мыши
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

func _unhandled_input(event: InputEvent) -> void:
	# Вращение камеры мышью
	if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
		camera_pivot.rotate_y(-event.relative.x * MOUSE_SENSITIVITY)
		# Ограничиваем вертикальный угол камеры
		var spring_arm = camera_pivot.get_node("SpringArm3D")
		spring_arm.rotate_x(-event.relative.y * MOUSE_SENSITIVITY)
		spring_arm.rotation.x = clamp(spring_arm.rotation.x, deg_to_rad(-60), deg_to_rad(30))

	# Выход из режима захвата мыши по Esc
	if event.is_action_pressed("ui_cancel"):
		Input.mouse_mode = Input.MOUSE_MODE_VISIBLE

func _physics_process(delta: float) -> void:
	# 1. Гравитация
	if not is_on_floor():
		velocity.y -= gravity * delta

	# 2. Прыжок
	if Input.is_action_just_pressed("jump") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# 3. Обработка Рывка (Dash)
	if Input.is_action_just_pressed("dash") and not is_dashing:
		start_dash()

	if is_dashing:
		dash_timer -= delta
		velocity.x = dash_direction.x * DASH_SPEED
		velocity.z = dash_direction.z * DASH_SPEED
		if dash_timer <= 0:
			is_dashing = false
	else:
		# 4. Обычное перемещение относительно направления камеры
		var input_dir := Input.get_vector("move_left", "move_right", "move_forward", "move_back")
		var direction := (camera_pivot.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()

		if direction:
			velocity.x = direction.x * SPEED
			velocity.z = direction.z * SPEED
		else:
			velocity.x = move_toward(velocity.x, 0, SPEED)
			velocity.z = move_toward(velocity.z, 0, SPEED)

	move_and_slide()

func start_dash() -> void:
	is_dashing = true
	dash_timer = DASH_DURATION
	var input_dir := Input.get_vector("move_left", "move_right", "move_forward", "move_back")
	
	# Если нажат вектор движения — рывок идет туда, иначе — вперед по камере
	if input_dir != Vector2.ZERO:
		dash_direction = (camera_pivot.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	else:
		dash_direction = -camera_pivot.transform.basis.z.normalized()