Files
godot_test/scripts/player.gd
2025-08-08 16:36:54 +05:00

97 lines
3.5 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

extends CharacterBody3D
class_name Character
@export_group("Movement Settings")
@export var normal_speed: float = 6.0
@export var sprint_speed: float = 10.0
@export var jump_velocity: float = 10.0
@export var gravity_scale: float = 1.0
@export var rotation_speed: float = 10.0
@export var acceleration: float = 10.0 # Сила ускорения
@export var deceleration: float = 8.0 # Сила замедления
@export_group("References")
@export var body: Node3D = null
@export var spring_arm_offset: Node3D = null
@export var respawn_point: Vector3 = Vector3(0, 5, 0)
var _current_speed: float
var _target_velocity: Vector3 = Vector3.ZERO # Целевая скорость
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
var _has_input: bool = false
var _can_sprint: bool = true
func _ready():
$SpringArmOffset/SpringArm3D/Camera3D.current = false
func _physics_process(delta):
# Обработка гравитации
if not is_on_floor():
velocity.y -= gravity * delta
_can_sprint = false # В воздухе нельзя ускоряться
else:
_can_sprint = true # На земле можно ускоряться
# Обработка прыжка
if is_on_floor() and Input.is_action_just_pressed("jump"):
velocity.y = jump_velocity
_can_sprint = false # При прыжке сразу отключаем спринт
_move(delta)
move_and_slide()
if body and body.has_method("animate"):
body.animate(velocity)
func _process(_delta):
_check_fall_and_respawn()
func _move(delta: float) -> void:
var input_direction = Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
_has_input = input_direction.length() > 0.1
# Получаем направление движения относительно камеры
var camera_basis = $SpringArmOffset/SpringArm3D/Camera3D.global_transform.basis
var direction = (camera_basis * Vector3(input_direction.x, 0, input_direction.y)).normalized()
_update_speed()
if direction:
# Устанавливаем целевую скорость с учетом направления
_target_velocity.x = direction.x * _current_speed
_target_velocity.z = direction.z * _current_speed
# Плавно изменяем скорость в сторону целевой
velocity.x = lerp(velocity.x, _target_velocity.x, acceleration * delta)
velocity.z = lerp(velocity.z, _target_velocity.z, acceleration * delta)
# Поворачиваем тело персонажа в направлении движения
if velocity.length() > 0.1:
var target_rotation = atan2(_target_velocity.x, _target_velocity.z)
body.rotation.y = lerp_angle(body.rotation.y, target_rotation, rotation_speed * delta)
else:
# Если нет ввода, плавно уменьшаем скорость
_target_velocity = Vector3.ZERO
velocity.x = lerp(velocity.x, 0.0, deceleration * delta)
velocity.z = lerp(velocity.z, 0.0, deceleration * delta)
func is_running() -> bool:
return Input.is_action_pressed("shift") and _current_speed == sprint_speed
func _update_speed() -> void:
# Ускорение работает только когда персонаж на земле
if _can_sprint and Input.is_action_pressed("shift"):
_current_speed = sprint_speed
else:
_current_speed = normal_speed
func _check_fall_and_respawn():
if global_transform.origin.y < -15.0:
_respawn()
func _respawn():
global_transform.origin = respawn_point
velocity = Vector3.ZERO
_target_velocity = Vector3.ZERO
_can_sprint = true