Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extends CharacterBody3D
- # Переменные
- const ACCEL = 10
- const DEACCEL = 30
- const SPEED = 3.5
- const MOUSE_SENSITIVITY = 0.06
- var dir = Vector3.ZERO
- var pos1
- var pos1_
- var rot1
- var fov1 = 75
- var pos2
- var pos2_
- var rot2
- var fov2 = 75
- var motion_time = 2
- var ease = false
- @onready var rotation_helper = $Cam
- @onready var logi = $Control/Panel/log
- func _ready():
- # Захватываем мышь
- Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
- Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
- # Ставим отображение дефолтных значений на панели
- $Control/settings/speed.text = 'Скорость анимации (в секундах): ' + str($Control/settings/speed_slider.value)
- $Control/settings/fov_slider_text.text = 'FOV камеры на старте: ' + str(fov1)
- $Control/settings/fov_slider_text2.text = 'FOV камеры на финише: ' + str(fov2)
- func _input(event):
- # Если действие (ивент) - это движение мыши и мышь захвачена приложением, то выполняется код
- if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
- # rotation_helper - это объект, который по иерархии стоит выше камеры и включает в себя камеру. Соответственно он имеет собственное вращение, но при этом его вращение также влияет на вращение камеры
- # Эта строчка вращает rotation_helper, конвертируя угол из градусов в радианы для дальнейших вычислений, умножая на сенсу мыши и инвертируя значение
- rotation_helper.rotate_x(deg_to_rad(event.relative.y * MOUSE_SENSITIVITY * -1))
- # Поворот камеры по У, также конвертируя угол из градусов в радианы, умножая на сенсу и инвертируя
- self.rotate_y(deg_to_rad(event.relative.x * MOUSE_SENSITIVITY * -1))
- # Объявляем переменную))
- var camera_rot = rotation_helper.rotation
- # Эта строчка берёт значение поворота камеры по иксу и ограничивает его в пределах от -1.4 до 1.4
- camera_rot.x = clampf(camera_rot.x, -1.4, 1.4)
- # Устанавливает поворот "ротейшн хелпера" в поворот камеры, учитывая ограничения выше
- rotation_helper.rotation = camera_rot
- # Скрипт захвата и отпускания мыши + появления панели по нажатию на F
- if Input.is_action_just_pressed("menu"):
- if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE:
- $Control/settings.visible = false
- Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
- else:
- Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
- $Control/settings.visible = true
- func _physics_process(delta):
- print(ease)
- # Отправляю кнопки управления в отдельную функцию, чисто для удобства чтения кода
- controls()
- # Считываем нажатия клавиш WASD, получаем из этого вектор и пихаем в отдельную переменную
- var input_dir = Input.get_vector("move_left", "move_right", "move_front", "move_back")
- # Устанавливаем вектор движения камеры из поворота мышью и вектора клавиш WASD, домножаем на delta - переменная движка, которая равна времени кадра.
- # Домножение на неё нужно для того, чтобы физика игры, ака время тика, не привязывался к ФПС
- var direction = (transform.basis * Vector3(input_dir.x, rotation_helper.rotation.x, input_dir.y)).normalized() * ACCEL * delta
- # Если у нас есть вектор, так сказать, предварительного движения (поворот камеры и нажатия WASD не равны нулю), то устанавливаем его значение в велосити
- if direction:
- velocity.x = direction.x * SPEED
- velocity.z = direction.z * SPEED
- # Если вектор "предварительного движения" пуст, то останавливаем движение по оси X и Z (в этом движке ось У - это верх/вниз)
- else:
- velocity.x = move_toward(velocity.x, 0, SPEED)
- velocity.z = move_toward(velocity.z, 0, SPEED)
- # Небольшой костыль)) Если есть вектор нажатия WS, то меняется вектор движения по Y, то есть движение вверх/вниз. В противном случае, если камера смотрит в пол и
- # ты перемещаешься вбок по кнопкам A и D, то камера опускается вниз. Короче это нужно для адекватного управления
- if input_dir.y: velocity.y = direction.y * SPEED
- else: velocity.y = 0
- if input_dir.y > 0: velocity.y *= -1
- # Команда, которая говорит движку начать движение по вектору velocity, который мы ранее устанавливали
- move_and_slide()
- func controls():
- # По нажатию ЛКМ устанавливается в переменную pos1 текущая позиция + отчёт в логах + телепортация маркера
- if Input.is_action_just_pressed("LKM") && Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
- pos1 = self.global_transform
- pos1_ = rotation_helper.global_transform
- logi.text += '\n[color=orange]Старт [/color]установлен'
- get_parent().get_node("markers/pos1").global_position = self.global_position
- # По нажатию ПКМ устанавливается в переменную pos2 текущая позиция + отчёт в логах + телепортация маркера
- if Input.is_action_just_pressed('PKM'):
- pos2 = self.global_transform
- pos2_ = rotation_helper.global_transform
- logi.text += '\n[color=cyan]Финиш [/color]установлен'
- get_parent().get_node("markers/pos2").global_position = self.global_position
- # По нажатию пробела, если стартовая позиция существует, то камера устанавливается в стартовую позицию
- if Input.is_action_just_pressed('space'):
- # Проверка есть ли точка старта и финиша
- if !pos1 or !pos2:
- logi.text += '\n[color=red]ОШИБКА! [/color]Не установлена точка старта или финиша!'
- else:
- logi.text += '\nПошла жара'
- if pos1: global_transform = pos1
- if pos1_: rotation_helper.global_transform = pos1_
- if fov1: $Cam/Camera3D.fov = fov1
- # Плавное перемещение камеры из pos1 в pos2 (из старта к финишу), а также изменение FOV и поворота по Y
- # Разнёс всё по разным функциям, чтобы они выполнялись паралелльно, а не ждали, пока пройдёт анимация
- pos_change()
- fov_change()
- rot_helper_change()
- func pos_change():
- if ease:
- # Создание объекта, позволяющего управлять анимациями из кода
- var tween_pos_ease = create_tween()
- # Анимация с интерполяцией
- tween_pos_ease.tween_property(self, "global_transform", pos2, motion_time).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT)
- else:
- var tween_pos = create_tween()
- # Анимация без интерполяции
- tween_pos.tween_property(self, "global_transform", pos2, motion_time).set_trans(Tween.TRANS_LINEAR)
- func fov_change():
- # Анимирует значение FOV
- var tween_fov = create_tween()
- if ease: tween_fov.tween_property($Cam/Camera3D, "fov", fov2, motion_time).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT)
- else: tween_fov.tween_property($Cam/Camera3D, "fov", fov2, motion_time).set_trans(Tween.TRANS_LINEAR)
- func rot_helper_change():
- # Анимирует поворот камеры по Y. Вынес в отдельную функцию, так как поворот по Y находится в другом объекте
- var tween_rot = create_tween()
- if ease: tween_rot.tween_property(rotation_helper, "global_transform", pos2_, motion_time).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT)
- else: tween_rot.tween_property(rotation_helper, "global_transform", pos2_, motion_time).set_trans(Tween.TRANS_LINEAR)
- func _on_speed_slider_value_changed(value):
- # Функция "Если значение слайдера скорости изменилось, то изменить отображение текста в панели в соответствии со значением + само значение скорости поменять на значение слайдера"
- $Control/settings/speed.text = 'Скорость анимации (в секундах): ' + str($Control/settings/speed_slider.value)
- motion_time = $Control/settings/speed_slider.value
- func _on_fov_slider_start_value_changed(value):
- # Полностью аналогично функции выше, только FOV старта
- fov1 = $Control/settings/fov_slider_start.value
- $Cam/Camera3D.fov = fov1
- $Control/settings/fov_slider_text.text = 'FOV камеры на старте: ' + str(fov1)
- func _on_fov_slider_finish_2_value_changed(value):
- # Полностью аналогично функции выше х2, только FOV финиша
- fov2 = $Control/settings/fov_slider_finish2.value
- $Cam/Camera3D.fov = fov2
- $Control/settings/fov_slider_text2.text = 'FOV камеры на финише: ' + str(fov2)
- func _on_vis_point_pressed():
- # Функция показать/спрятать маркеры по нажатию на соответствующий ползунок
- get_parent().get_node('markers').visible = $Control/settings/vis_point.button_pressed
- func _on_interpol_pressed():
- # Функция, включаюащя интерполяцию по нажатию на соответствующий ползунок
- ease = $Control/settings/interpol.button_pressed
- func _on_vis_log_pressed():
- # Функция, показать/спрятать логи по нажатию на соответствующий ползунок
- $Control/Panel.visible = $Control/settings/vis_log.button_pressed
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement