Advertisement
yohohloma

Untitled

Jan 5th, 2024 (edited)
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
GDScript 10.84 KB | None | 0 0
  1. extends CharacterBody3D
  2.  
  3.  
  4. # Переменные
  5.  
  6. const ACCEL = 10
  7. const DEACCEL = 30
  8.  
  9. const SPEED = 3.5
  10. const MOUSE_SENSITIVITY = 0.06
  11.  
  12. var dir = Vector3.ZERO
  13.  
  14. var pos1
  15. var pos1_
  16. var rot1
  17. var fov1 = 75
  18.  
  19. var pos2
  20. var pos2_
  21. var rot2
  22. var fov2 = 75
  23.  
  24. var motion_time = 2
  25. var ease = false
  26.  
  27. @onready var rotation_helper = $Cam
  28. @onready var logi = $Control/Panel/log
  29.  
  30.  
  31. func _ready():
  32.     # Захватываем мышь
  33.     Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
  34.     Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
  35.    
  36.     # Ставим отображение дефолтных значений на панели
  37.     $Control/settings/speed.text = 'Скорость анимации (в секундах): ' + str($Control/settings/speed_slider.value)
  38.     $Control/settings/fov_slider_text.text = 'FOV камеры на старте: ' + str(fov1)
  39.     $Control/settings/fov_slider_text2.text = 'FOV камеры на финише: ' + str(fov2)
  40.    
  41. func _input(event):
  42.     # Если действие (ивент) - это движение мыши и мышь захвачена приложением, то выполняется код
  43.     if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
  44.         # rotation_helper - это объект, который по иерархии стоит выше камеры и включает в себя камеру. Соответственно он имеет собственное вращение, но при этом его вращение также влияет на вращение камеры
  45.         # Эта строчка вращает rotation_helper, конвертируя угол из градусов в радианы для дальнейших вычислений, умножая на сенсу мыши и инвертируя значение
  46.         rotation_helper.rotate_x(deg_to_rad(event.relative.y * MOUSE_SENSITIVITY * -1))
  47.         # Поворот камеры по У, также конвертируя угол из градусов в радианы, умножая на сенсу и инвертируя
  48.         self.rotate_y(deg_to_rad(event.relative.x * MOUSE_SENSITIVITY * -1))
  49.         # Объявляем переменную))
  50.         var camera_rot = rotation_helper.rotation
  51.         # Эта строчка берёт значение поворота камеры по иксу и ограничивает его в пределах от -1.4 до 1.4
  52.         camera_rot.x = clampf(camera_rot.x, -1.4, 1.4)
  53.         # Устанавливает поворот "ротейшн хелпера" в поворот камеры, учитывая ограничения выше
  54.         rotation_helper.rotation = camera_rot
  55.    
  56.     # Скрипт захвата и отпускания мыши + появления панели по нажатию на F
  57.     if Input.is_action_just_pressed("menu"):
  58.         if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE:
  59.             $Control/settings.visible = false
  60.             Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
  61.         else:
  62.             Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
  63.             $Control/settings.visible = true
  64.  
  65. func _physics_process(delta):
  66.     print(ease)
  67.     # Отправляю кнопки управления в отдельную функцию, чисто для удобства чтения кода
  68.     controls()
  69.     # Считываем нажатия клавиш WASD, получаем из этого вектор и пихаем в отдельную переменную
  70.     var input_dir = Input.get_vector("move_left", "move_right", "move_front", "move_back")
  71.     # Устанавливаем вектор движения камеры из поворота мышью и вектора клавиш WASD, домножаем на delta - переменная движка, которая равна времени кадра.
  72.     # Домножение на неё нужно для того, чтобы физика игры, ака время тика, не привязывался к ФПС
  73.     var direction = (transform.basis * Vector3(input_dir.x, rotation_helper.rotation.x, input_dir.y)).normalized() * ACCEL * delta
  74.    
  75.     # Если у нас есть вектор, так сказать, предварительного движения (поворот камеры и нажатия WASD не равны нулю), то устанавливаем его значение в велосити
  76.     if direction:
  77.         velocity.x = direction.x * SPEED
  78.         velocity.z = direction.z * SPEED
  79.     # Если вектор "предварительного движения" пуст, то останавливаем движение по оси X и Z (в этом движке ось У - это верх/вниз)
  80.     else:
  81.         velocity.x = move_toward(velocity.x, 0, SPEED)
  82.         velocity.z = move_toward(velocity.z, 0, SPEED)
  83.     # Небольшой костыль)) Если есть вектор нажатия WS, то меняется вектор движения по Y, то есть движение вверх/вниз. В противном случае, если камера смотрит в пол и
  84.     # ты перемещаешься вбок по кнопкам A и D, то камера опускается вниз. Короче это нужно для адекватного управления
  85.     if input_dir.y: velocity.y = direction.y * SPEED
  86.     else: velocity.y = 0
  87.    
  88.     if input_dir.y > 0: velocity.y *= -1
  89.     # Команда, которая говорит движку начать движение по вектору velocity, который мы ранее устанавливали
  90.     move_and_slide()
  91.  
  92.  
  93. func controls():
  94.     # По нажатию ЛКМ устанавливается в переменную pos1 текущая позиция + отчёт в логах + телепортация маркера
  95.     if Input.is_action_just_pressed("LKM") && Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
  96.         pos1 = self.global_transform
  97.         pos1_ = rotation_helper.global_transform
  98.         logi.text += '\n[color=orange]Старт [/color]установлен'
  99.         get_parent().get_node("markers/pos1").global_position = self.global_position
  100.     # По нажатию ПКМ устанавливается в переменную pos2 текущая позиция + отчёт в логах + телепортация маркера
  101.     if Input.is_action_just_pressed('PKM'):
  102.         pos2 = self.global_transform
  103.         pos2_ = rotation_helper.global_transform
  104.         logi.text += '\n[color=cyan]Финиш [/color]установлен'
  105.         get_parent().get_node("markers/pos2").global_position = self.global_position
  106.     # По нажатию пробела, если стартовая позиция существует, то камера устанавливается в стартовую позицию
  107.     if Input.is_action_just_pressed('space'):
  108.         # Проверка есть ли точка старта и финиша
  109.         if !pos1 or !pos2:
  110.             logi.text += '\n[color=red]ОШИБКА! [/color]Не установлена точка старта или финиша!'
  111.         else:
  112.             logi.text += '\nПошла жара'
  113.             if pos1: global_transform = pos1
  114.             if pos1_: rotation_helper.global_transform = pos1_
  115.             if fov1: $Cam/Camera3D.fov = fov1
  116.            
  117.             # Плавное перемещение камеры из pos1 в pos2 (из старта к финишу), а также изменение FOV и поворота по Y
  118.             # Разнёс всё по разным функциям, чтобы они выполнялись паралелльно, а не ждали, пока пройдёт анимация
  119.             pos_change()
  120.             fov_change()
  121.             rot_helper_change()
  122.  
  123. func pos_change():
  124.     if ease:
  125.         # Создание объекта, позволяющего управлять анимациями из кода
  126.         var tween_pos_ease = create_tween()
  127.         # Анимация с интерполяцией
  128.         tween_pos_ease.tween_property(self, "global_transform", pos2, motion_time).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT)
  129.     else:
  130.         var tween_pos = create_tween()
  131.         # Анимация без интерполяции
  132.         tween_pos.tween_property(self, "global_transform", pos2, motion_time).set_trans(Tween.TRANS_LINEAR)
  133.  
  134. func fov_change():
  135.     # Анимирует значение FOV
  136.     var tween_fov = create_tween()
  137.     if ease: tween_fov.tween_property($Cam/Camera3D, "fov", fov2, motion_time).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT)
  138.     else: tween_fov.tween_property($Cam/Camera3D, "fov", fov2, motion_time).set_trans(Tween.TRANS_LINEAR)
  139.  
  140. func rot_helper_change():
  141.     # Анимирует поворот камеры по Y. Вынес в отдельную функцию, так как поворот по Y находится в другом объекте
  142.     var tween_rot = create_tween()
  143.     if ease: tween_rot.tween_property(rotation_helper, "global_transform", pos2_, motion_time).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT)
  144.     else: tween_rot.tween_property(rotation_helper, "global_transform", pos2_, motion_time).set_trans(Tween.TRANS_LINEAR)
  145.  
  146. func _on_speed_slider_value_changed(value):
  147.     # Функция "Если значение слайдера скорости изменилось, то изменить отображение текста в панели в соответствии со значением + само значение скорости поменять на значение слайдера"
  148.     $Control/settings/speed.text = 'Скорость анимации (в секундах): ' + str($Control/settings/speed_slider.value)
  149.     motion_time = $Control/settings/speed_slider.value
  150.  
  151.  
  152. func _on_fov_slider_start_value_changed(value):
  153.     # Полностью аналогично функции выше, только FOV старта
  154.     fov1 = $Control/settings/fov_slider_start.value
  155.     $Cam/Camera3D.fov = fov1
  156.     $Control/settings/fov_slider_text.text = 'FOV камеры на старте: ' + str(fov1)
  157.  
  158.  
  159. func _on_fov_slider_finish_2_value_changed(value):
  160.     # Полностью аналогично функции выше х2, только FOV финиша
  161.     fov2 = $Control/settings/fov_slider_finish2.value
  162.     $Cam/Camera3D.fov = fov2
  163.     $Control/settings/fov_slider_text2.text = 'FOV камеры на финише: ' + str(fov2)
  164.  
  165. func _on_vis_point_pressed():
  166.     # Функция показать/спрятать маркеры по нажатию на соответствующий ползунок
  167.     get_parent().get_node('markers').visible = $Control/settings/vis_point.button_pressed
  168.  
  169.  
  170. func _on_interpol_pressed():
  171.     # Функция, включаюащя интерполяцию по нажатию на соответствующий ползунок
  172.     ease = $Control/settings/interpol.button_pressed
  173.  
  174.  
  175. func _on_vis_log_pressed():
  176.     # Функция, показать/спрятать логи по нажатию на соответствующий ползунок
  177.     $Control/Panel.visible = $Control/settings/vis_log.button_pressed
  178.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement