extends CharacterBody3D
@export var SPEED: float = 12.0
@export var DASH_SPEED: float = 28.0
@export var GRAVITY: float = 20.0
# Перетащим картинки лица и спины прямо в Инспектор игрока
@export var texture_back: Texture2D
@export var texture_front: Texture2D
# Чувствительность вращения камеры
@export var MOUSE_SENSITIVITY: float = 0.003
# Ограничения наклона камеры вверх/вниз
@export var MIN_PITCH: float = deg_to_rad(-60.0)
@export var MAX_PITCH: float = deg_to_rad(60.0)
@onready var sprite: Sprite3D = $Sprite3D
@onready var camera: Camera3D = $Camera3D
var camera_angle_x: float = 0.0
var camera_angle_y: float = 0.0
var camera_distance: float = 3.5
func _ready() -> void:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
if camera:
camera_angle_x = camera.rotation.x
camera_angle_y = camera.rotation.y
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_RIGHT:
if event.pressed:
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
else:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
camera_angle_y -= event.relative.x * MOUSE_SENSITIVITY
camera_angle_x -= event.relative.y * MOUSE_SENSITIVITY
camera_angle_x = clamp(camera_angle_x, MIN_PITCH, MAX_PITCH)
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity.y -= GRAVITY * delta
_update_camera_position()
var move_forward_backward: float = 0.0
if Input.is_key_pressed(KEY_W) or Input.is_action_pressed("ui_up"):
move_forward_backward -= 1.0
if Input.is_key_pressed(KEY_S) or Input.is_action_pressed("ui_down"):
move_forward_backward += 1.0
var direction := (transform.basis * Vector3(0, 0, move_forward_backward)).normalized()
if move_forward_backward != 0.0:
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()
_update_sprite_texture()
func _update_camera_position() -> void:
if not camera:
return
var offset = Vector3(
sin(camera_angle_y) * cos(camera_angle_x),
sin(camera_angle_x),
cos(camera_angle_y) * cos(camera_angle_x)
) * camera_distance
camera.position = offset + Vector3(0, 1.2, 0)
camera.look_at(global_position + Vector3(0, 1.0, 0), Vector3.UP)
func _update_sprite_texture() -> void:
if not sprite or not camera:
return
# Вычисляем направление от игрока к камере
var cam_dir = (camera.global_position - global_position).normalized()
# Направление "вперёд" самого игрока
var player_forward = -global_transform.basis.z.normalized()
# Проверяем, смотрим ли на игрока спереди
if player_forward.dot(cam_dir) > 0.0:
if texture_front:
sprite.texture = texture_front
else:
if texture_back:
sprite.texture = texture_back