Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Камера от третьего лица с пружинным рычагом

Введение

В 3D-играх часто используется камера от третьего лица, которая следует за персонажем игрока или транспортным средством и вращается вокруг него.

В Godot это можно сделать, установив Camera3D как дочерний элемент узла. Однако, если вы попробуете сделать это без дополнительных шагов, вы заметите, что камера обрезает геометрию и скрывает сцену.

Вот тут-то и пригодится узел SpringArm3D.

Что такое пружинный рычаг?

Пружинный рычаг состоит из двух основных компонентов, которые влияют на его поведение.

«Длина» пружинного рычага — это расстояние от его глобального положения, на котором необходимо проверять наличие столкновений:

../../_images/spring_arm_position_length.webp

«Форма» пружинного рычага — это то, что он использует для проверки столкновений. Пружинный рычаг «выметает» эту форму от ее начала по направлению к ее длине.

../../_images/spring_arm_shape.webp

Пружинный рычаг пытается удержать всех своих потомков в конце своей длины. Когда форма сталкивается с чем-то, потомки вместо этого размещаются в точке столкновения или около нее:

../../_images/spring_arm_children.webp

Пружинный рычаг с камерой

Если камера размещена как дочерний элемент пружинного рычага, в качестве формы будет использоваться пирамида, представляющая камеру.

Эта пирамида представляет собой near plane (ближнюю плоскость) камеры:

../../_images/spring_arm_camera_shape.webp

Примечание

Если пружинному рычагу придать определенную форму, то эта форма будет использоваться всегда.

Форма камеры используется только в том случае, если камера является прямым потомком пружинного рычага.

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

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

../../_images/spring_arm_camera_motion_cast.webp

Когда фигура сталкивается с чем-либо, камера будет помещена в точку столкновения или рядом с ней:

../../_images/spring_arm_camera_collision.webp

Установка пружинного рычага и камеры

Давайте добавим в демо-версию платформера камеру с пружинным рычагом.

Примечание

Вы можете загрузить демоверсию Platformer 3D на GitHub или с помощью Asset Library.

В общем случае для настройки камеры от третьего лица у вас будет три узла в качестве дочерних узлов узла, за которым вы следите:

  • Node3D («точка опоры» для камеры)

    • SpringArm3D

      • Camera3D

Откройте сцену player/player.tscn. Настройте их как дочерние элементы нашего игрока и дайте им уникальные имена, чтобы мы могли найти их в нашем скрипте. Обязательно удалите существующий узел камеры!

../../_images/spring_arm_editor_setup.webp

Давайте переместим точку опоры на 2 вверх по оси Y, чтобы она не находилась на земле:

../../_images/spring_arm_pivot_setup.webp

Придайте пружинному рычагу длину 3, чтобы он располагался позади персонажа:

../../_images/spring_arm_length_setup.webp

Примечание

Оставьте Shape (Форму) пружинного рычага как <empty>. Таким образом, он будет использовать форму пирамиды камеры.

При желании вы можете попробовать и другие формы — сфера является распространенным выбором, поскольку она плавно скользит по краям.

Обновите верхнюю часть player/player.gd, чтобы получить камеру и точки поворота по их уникальным именам:

player/player.gd
# Comment out this existing camera line.
# @onready var _camera := $Target/Camera3D as Camera3D

@onready var _camera := %Camera3D as Camera3D
@onready var _camera_pivot := %CameraPivot as Node3D

Добавьте функцию _unhandled_input для проверки движения камеры, а затем поверните точку поворота соответствующим образом:

player/player.gd
@export_range(0.0, 1.0) var mouse_sensitivity = 0.01
@export var tilt_limit = deg_to_rad(75)


func _unhandled_input(event: InputEvent) -> void:
    # Mouselook implemented using `screen_relative` for resolution-independent sensitivity.
    if event is InputEventMouseMotion:
        _camera_pivot.rotation.x -= event.screen_relative.y * mouse_sensitivity
        # Prevent the camera from rotating too far up or down.
        _camera_pivot.rotation.x = clampf(_camera_pivot.rotation.x, -tilt_limit, tilt_limit)
        _camera_pivot.rotation.y += -event.screen_relative.x * mouse_sensitivity

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