#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

Приступим. Сегодня в меню:

  • добавление камеры, следующей за игровым персонажем;
  • сглаживание движения камеры с помощью функции lerp().

Если мы посмотрим на наш текущий проект, то заметим (это сложно не заметить), что камера статична и не меняет своего положения при перемещениях объекта персонажа игрока.

Такое поведение камеры нас не устраивает, поэтому приступим.

Для того, чтобы исправить поведение камеры, нам нужно... удалить текущую камеру из сцены Level1. Дело в том, что мы добавим камеру в сцену Steve, содержащую игрового персонажа, что позволит нам изящно решить вопрос перемещения камеры за игроком, а также пригодится на случай использования игрового персонажа на других уровнях (читай - сценах) нашей игры. Поэтому отдельная камера на уровне нам не нужна - мы будем использовать камеру, привязанную к персонажу.

Итак, во вкладке level_1 в панели Сцена кликаем правой кнопкой мыши на узел Camera3D и выбираем Удалить (Delete).

#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

Переходим во вкладку steve и в панели Сцена добавляем к корневому узел Steve дочерний узел Camera3D.

#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

В целом мы уже сейчас можем просто поменять положение камеры на более выгодное...

#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

...поставить для узла Camera3D в панели Инспектор галочку напротив свойства Current...

#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

...и получить вот такой результат

В целом задача решена, но при таком подходе камера не меняет своего положения вообще - а хочется иметь в том числе режим со свободной камерой, чтобы свободно вращать её и вертеть. Поэтому мы пойдём другим путём.

После создания узла Camera3D создаём ещё один дочерний узел Node3D, и переименовываем его как Camera_Controller.

#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

К узлу Camera_Controller добавляем дочерний узел Node3D, который переименовываем как Camera_Target.

#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

Узел Camera_Target перемещаем вдоль положительного направления оси Z и приподнимаем. Затем в верхней части рабочего пространства нажимаем на кнопку Использовать локальное пространство (Т)...

#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

И слегка наклоняем узел в сторону игрового персонажа (без включения опции Использовать локальное пространство узел Node3D не отражает изменения положения вращения).

#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

Затем в панели Сцена перетаскиваем узел Camera3D в узел Camera_Target.

#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

Теперь узел Camera3D является дочерним для узла Camera_Target.

#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

Сейчас камера находится в центре координатной сетки.

#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

Для того, чтобы переместить её туда же, где расположен узел Camera_Target, в панели Инспектор раскрываем группу свойств Transform и сбрасываем значения параметров Position и Rotation до нулевых.

Вот эти параметры, ещё не сброшены
Вот эти параметры, ещё не сброшены

После сброса камера перемещается точно к своему родительскому узлу Camera_Target.

После сброса я немного подкрутил узел Camera_Target вверх, чтобы центр камеры смотрел чуть выше игрового персонажа - при этом сбрасывать координаты узла Camera3D уже не требовалось, камера сама вращалась вместе с родительским узлом
После сброса я немного подкрутил узел Camera_Target вверх, чтобы центр камеры смотрел чуть выше игрового персонажа - при этом сбрасывать координаты узла Camera3D уже не требовалось, камера сама вращалась вместе с родительским узлом

Если мы запустим проект сейчас, то увидим, что у нас получилось всё то же самое, что могло получиться и раньше.

Однако камера всё ещё привязана к игровому персонажу, поэтому мы идём дальше.

В панели Сцена выделяем узел Camera_Controller и в панели Инспектор ставим галочку напротив параметра Top Level.

#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

После этого мы увидим, что камера снова не привязана к игровому персонажу - потому что параметр Top Level как раз отвечает за то, чтобы узел не наследовал изменения координат родительского узла.

Теперь переходим во вкладку с кодом (можно сделать с помощью соответствующей иконки рядом с корневым узлом Steve).

#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

Нам нужно сделать так, чтобы узел Camera_Controller изменял своё положение так же, как и наш игровой персонаж, причём постоянно в процессе игры. Для этого в функции _physics_process мы напишем такие строки кода:

$Camera_Controller.position = position
#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

Символ $ позволяет нам обратиться к дочернему узлу, в данном случае - к узлу Camera_Controller. Остальное же - дело техники: мы просто присваиваем значения параметров позиции игрового персонажа параметрам позиции дочернего узла Camera_Controller. Вот что получается в итоге:

Однако есть проблема: статтеры при изменении направления движения игрового персонажа - задержка хоть и небольшая, но присутствует постоянно и хорошо заметна. Дело в том, что мы сначала перемещаем камеру с помощью строчки нашего кода, а затем уже меняем положение игрового персонажа с помощью вызова метода move_and_slide(). Поэтому, если мы переместим перемещение (каламбур) камеры после вызова данного метода,

вот так
вот так

то получим нормальный результат.

Теперь поработаем над плавностью камеры. Плавность обеспечим применением функции lerp(start, end, factor), которая принимает три аргумента:

  • start - начальное значение, в нашем случае - текущее положение камеры, то есть $Camera_Controller.position
  • end - конечное значение, в нашем случае - положение игрового персонажа, то есть position
  • factor - число между 0 и 1, которое определяет степень интерполяции, в нашем случае - определяет скорость изменения положения камеры за один фрейм. Для примера установим значение в 1%, то есть 0.01
$Camera_Controller.position = lerp($Camera_Controller.position, position, 0.01)
#8 Godot: 3D Platformer от BornCG. Привязка камеры к игроку

Посмотрим на результат

Очень уж медленно) попробуем 5%, то есть 0.05

Чего-то не хватает... поставим 0.15 и получим отличный результат: замедление камеры есть, но небольшое и оно не мешает динамичной игре. Обратите внимание на прикольный эффект отдаления камеры при загрузке уровня.

На сегодня, пожалуй, и всё. Пора пить чай и думать о будущем

И о Голден Бое тоже
И о Голден Бое тоже
9
2
2 комментария