~2 мин чтения

Камера и Phantom Camera

Camera3D, виды от первого/третьего лица, и плагин-аналог Cinemachine.

Camera3D — главный узел

Camera3D — узел, который “смотрит” в сцену. Только одна Camera3D активна в любой момент (если не используете отдельные viewports). У сцены может быть несколько камер; активная — та, у которой current = true, или которая стала активной через make_current().

Главные свойства:

  • projectionPERSPECTIVE (3D, с перспективой) или ORTHOGONAL (без, для изометрии/2.5D).
  • fov — поле зрения в градусах по вертикали. Стандарт FPS — 60–90°.
  • near, far — clipping planes. Большой разброс портит точность Z-buffer (Z-fighting).
  • cull_mask — битмаска: какие visual layers рендерит эта камера.
@onready var camera: Camera3D = $Head/Camera3D

func _ready() -> void:
    camera.fov = 75.0
    camera.near = 0.05
    camera.far = 500.0

Простой follow

Аналог Unity-варианта со SmoothDamp. В Godot нет встроенной SmoothDamp, но есть lerp:

extends Camera3D

@export var target: Node3D
@export var offset: Vector3 = Vector3(0, 2.0, 4.0)  # за спиной, выше
@export var smoothing: float = 5.0

func _process(delta: float) -> void:
    if target == null:
        return
    var desired = target.global_position + target.global_transform.basis * offset
    global_position = global_position.lerp(desired, smoothing * delta)
    look_at(target.global_position + Vector3.UP * 1.5, Vector3.UP)

vector.lerp(to, weight) — метод Vector3 для линейной интерполяции. look_at(target, up_vector) — направляет “вперёд” (−Z) камеры на цель.

Camera follow — в _process, не _physics_process

Если двигать камеру в _physics_process, на кадрах между физтиками она “застрянет” и будет выглядеть дёрганой. Камера — это рендер-задача, её место в _process. Если игрок — CharacterBody3D с физикой, его позицию интерполируйте либо включите глобальную physics interpolation в Project Settings (с 4.3).

Phantom Camera — Cinemachine-аналог

Godot core не имеет ничего уровня Unity Cinemachine. Но есть Phantom Camera — популярный community-плагин (ramokz/phantom-camera в Asset Store / Godot Asset Library). Дает виртуальные камеры с blendами, follow / look-at modes, framing, dead zones, hosts.

Установка: AssetLib (внутри редактора) → ищите “Phantom Camera” → Install. Активируется в Project → Project Settings → Plugins.

Базовая follow-camera в Phantom Camera

Player                            ← CharacterBody3D
└── PhantomCamera3D_Follow        ← виртуальная камера (follow_mode = ThirdPerson)

PhantomCameraHost                 ← один на сцену, висит на главной Camera3D
└── Camera3D                      ← реальная камера

Параметры виртуальной камеры:

  • Follow ModeSimple, Group, Path, Framed, ThirdPerson.
  • Look At ModeNone, Simple, Group, Mimic.
  • Tween Resource — кривая и длительность блендинга при переключении.
  • Priority — приоритет; PhantomCameraHost автоматически выбирает камеру с наибольшим.
# Переключение виртуальных камер
$PhantomCamera3D_FirstPerson.priority = 20
$PhantomCamera3D_ThirdPerson.priority = 10
# Host плавно переедет на FirstPerson
Phantom Camera — must-have для серьёзных 3D-проектов

Если ваша игра требует кат-сцен, переключений вид-от-первого/третьего лица, drone-камеры или тонкого framing — поставьте плагин с самого старта. Писать всё это вручную долго и хрупко.

Поворот камеры мышью (FPS)

Уже видели в главе про ввод, но повторим в контексте камеры:

extends CharacterBody3D

@onready var head: Node3D = $Head
@onready var camera: Camera3D = $Head/Camera3D

@export var sensitivity: float = 0.003
const MAX_PITCH: float = 1.4

func _ready() -> void:
    Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

func _unhandled_input(event: InputEvent) -> void:
    if event is InputEventMouseMotion:
        # yaw — поворот тела игрока (влияет на направление движения)
        rotate_y(-event.relative.x * sensitivity)
        # pitch — только голова, тело не наклоняется
        head.rotate_x(-event.relative.y * sensitivity)
        head.rotation.x = clamp(head.rotation.x, -MAX_PITCH, MAX_PITCH)

Иерархия:

Player (CharacterBody3D)        ← rotate_y (yaw)
├── CollisionShape3D
└── Head (Node3D)                ← rotate_x (pitch)
    └── Camera3D                  ← position (0, 0, 0)

Pitch (вертикаль) применяется к Head, чтобы коллайдер игрока не наклонялся, когда вы смотрите в небо.

Несколько viewports — split screen, мини-карты

Для split-screen или картинки-в-картинке используют SubViewport + SubViewportContainer:

SubViewportContainer (растягивается на пол-экрана)
└── SubViewport
    └── Camera3D (current = true)
    └── (то же 3D-мир, но через World3D-shared)

SubViewport.world_3d = main_viewport.world_3d — обе камеры рендерят одну сцену.

Виды проекции

Camera3D.projection влияет на ощущение:

  • PERSPECTIVE — естественное 3D с уменьшением далёких объектов.
  • ORTHOGONAL — без перспективы. Свойство size задаёт ширину видимой области. Подходит для изометрии, технических визуализаций, 2.5D.
  • FRUSTUM — продвинутая ассиметричная проекция (off-axis). Редко нужно — VR, спецэффекты.

В следующей главе — рендеринг.