Files
aego/modules/camera/res/docs/camera.ru.md
sanspie f22242e5aa
ci / release (push) Successful in 5m5s
ci-platforms / build (amd64, windows, windows-2022) (push) Skipped
ci-platforms / build (arm64, darwin, macos-15) (push) Skipped
ci-platforms / build (amd64, darwin, macos-15-intel) (push) Skipped
ci / checks (push) Successful in 4m41s
ci / build (amd64, linux, ubuntu-24.04) (push) Successful in 7m14s
Stage 11g2–11g3: registry texts, CLI and the site in Russian (D348)
The remaining editor strings and undo step names; component, field, enum, setting, diagnostic and Script API texts under schema.*, enum.*, setting.*, diag.* and api.*; the launcher, the in-game Settings View with a Language setting, the CLI and aego schema show --lang. Every documentation page has a .ru.md translation; the site has a full Russian tree with hreflang, a language switch and ru/llms.txt; aego docs check --lang ru. New doc.tutorial and doc.recipe icons. Fix: an animator restored by a rewind prepares its controller before the replayed step.
2026-10-25 15:31:22 +03:00

246 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: camera
title: Камеры 2D
group: camera
group_title: Камеры 2D
---
# Камеры 2D
[«Камера 2D»](ref:engine.Camera2D) рисует вид, а виртуальные камеры решают, куда она смотрит. Каждая [«Виртуальная камера 2D»](ref:camera.VirtualCamera2D) — возможная поза. Видом управляет включённая камера с наибольшим приоритетом, а переключение между камерами идёт плавным переходом. Слежение, тряска и зоны — компоненты на виртуальных камерах; скрипты их запускают.
Быстрый старт: **Создать → Следящая камера** даёт узел с «Камерой 2D», «Виртуальной камерой 2D» и «Слежением камеры 2D». Укажите игрока в поле «Цель» и нажмите **Играть**.
| Компонент | Назначение |
|---|---|
| Виртуальная камера 2D | поза с приоритетом, масштабом, границами и переходом |
| Слежение камеры 2D | ведёт свою виртуальную камеру за целью |
| Тряска камеры 2D | настраивает тряску своей виртуальной камеры |
| Зона камеры 2D | поднимает камеру, пока цель внутри области |
| Мозг камеры 2D | заставляет «Камеру 2D» показывать другой выход |
Камеры работают во время игры и в `aego run`. В режиме редактирования панель «Сцена» показывает рамку камеры, мёртвую зону, границы и зоны.
---
id: camera/virtual
title: Виртуальные камеры
---
# Виртуальные камеры
Каждый кадр мозг выбирает по одной виртуальной камере на выход:
1. Включённая виртуальная камера с наибольшим [Приоритетом](ref:camera.VirtualCamera2D.Priority). При равных приоритетах выбирается камера, созданная раньше.
2. [«Зона камеры 2D»](ref:camera.CameraZone2D), внутри которой находится цель, поднимает свою камеру до приоритета зоны. При равенстве зона побеждает обычную камеру, а зона, в которую вошли позже, — более раннюю.
3. `camera.BlendTo` и `camera.Cut` перекрывают всё до вызова `camera.Release`.
Поза берётся из узла виртуальной камеры: его интерполированная позиция и поворот, а также [Масштаб](ref:camera.VirtualCamera2D.Zoom); 0 оставляет масштаб «Камеры 2D». «Слежение камеры 2D» на том же узле заменяет позицию. Трансформация узла никогда не меняется; камера двигает только вид.
В «Попробовать» скрипт Director по очереди поднимает **Close** и **Tilt**, каждую на две секунды, и вид плавно переходит к ним и обратно. Измените у Close «Масштаб», «Время перехода» или «Кривую перехода» в Инспекторе и посмотрите на следующий переход; скрипт лежит под сценой.
## Переходы
Когда активной становится другая камера, вид переходит от позы, которую показывает сейчас, к новой камере за её [Время перехода](ref:camera.VirtualCamera2D.BlendTime) по [Кривой перехода](ref:camera.VirtualCamera2D.BlendCurve). Переключение во время перехода начинается от текущего вида, а не от старой камеры. Масштаб меняется на экране равномерно. «Время перехода» 0 переключает сразу.
## Границы
[«Использовать границы»](ref:camera.VirtualCamera2D.UseBounds) держит видимую область внутри [Границ](ref:camera.VirtualCamera2D.Bounds) — прямоугольника в мире. Если по какой-то оси область меньше вида, вид центрируется на ней по этой оси.
---
id: camera/outputs
title: Выходы
---
# Выходы
Виртуальные камеры управляют главным выходом, если их [Выход](ref:camera.VirtualCamera2D.Output) не называет другой. «Камера 2D» показывает главный выход; добавьте [«Мозг камеры 2D»](ref:camera.CameraBrain2D) с тем же выходом, чтобы она показывала другой, например мини-карту. У каждого выхода своя активная камера, свои переходы и своя тряска. «Камера 2D», у выхода которой нет виртуальных камер, остаётся как есть.
В «Попробовать» мини-карта в углу — вторая «Камера 2D» с маленькой «Областью вывода» и «Мозгом камеры 2D» с выходом `map`; её собственная виртуальная камера следит за мячом издалека.
---
id: camera/follow
title: Слежение
---
# Слежение
[«Слежение камеры 2D»](ref:camera.CameraFollow2D) ведёт свою виртуальную камеру за [Целью](ref:camera.CameraFollow2D.Target).
Внутри **Мёртвой зоны** — части вида — цель движется свободно; (0.4, 0.4, 0.2, 0.2) — пятая часть в центре. Снаружи камера догоняет цель со скоростью, которую задаёт **Демпфирование**; при 0 камера следует жёстко.
**Упреждение** сдвигает камеру вперёд движущейся цели на столько секунд её скорости. **Макс. упреждение** ограничивает этот сдвиг, а **Сглаживание упреждения** — скорость его изменения. Когда цель прыгает дальше **Расстояния скачка**, например после телепорта, камера перемещается сразу.
Все поля с единицами измерения перечислены на странице [«Слежение камеры 2D»](ref:camera.CameraFollow2D).
![Выбрано «Слежение камеры 2D»: жёлтая мёртвая зона, линия к цели и границы](shots/camera-follow.png)
Камера следует за интерполированной позой физического тела, поэтому движется плавно при любой частоте кадров. Демпфирование экспоненциальное: камера при 30, 60 и 144 кадрах в секунду приходит в одно и то же место. Когда цель телепортируется, вызовите `Snap()` у компонента или положитесь на «Расстояние скачка».
В «Попробовать» мяч катится по длинному склону. Поставьте «Демпфирование» в 0 для жёсткой камеры или расширьте «Мёртвую зону», чтобы мяч убегал вперёд.
---
id: camera/zones
title: Зоны
---
# Зоны
[«Зона камеры 2D»](ref:camera.CameraZone2D) меняет камеру, пока цель находится внутри её [Области](ref:camera.CameraZone2D.Area) — прямоугольника в пространстве узла зоны. Внутри [Камера](ref:camera.CameraZone2D.Camera) получает [Приоритет](ref:camera.CameraZone2D.Priority), [Масштаб](ref:camera.CameraZone2D.Zoom) и [Границы](ref:camera.CameraZone2D.Bounds) зоны; снаружи всё возвращается как было. Поля самой камеры никогда не меняются.
- Пустая «Камера» берёт виртуальную камеру на узле зоны; дайте ей низкий приоритет, чтобы она показывалась только через зону.
- Пустая «Цель» берёт цель слежения камеры зоны.
- Зоны используют точную позицию цели, а не интерполированную, поэтому один и тот же ввод всегда входит в зону на одном и том же кадре.
- Перекрывающиеся зоны: побеждает больший приоритет, затем зона, в которую вошли позже. Выход из одной зоны не влияет на другие.
В «Попробовать» фиолетовая область посреди склона — это зона: пока мяч катится через неё, вид переходит к более близкому неподвижному кадру, а после — обратно к следящей камере.
![Выбрана «Зона камеры 2D»: её область с маркерами над ареной](shots/camera-zone.png)
---
id: camera/shake
title: Тряска
---
# Тряска
В «Попробовать» ящик падает каждые две секунды, и при приземлении его скрипт вызывает `camera.Shake(0.9)`. Увеличьте «Макс. угол» или уменьшите «Степень» и «Затухание» у камеры, чтобы почувствовать разницу.
Тряской управляет травма — значение от 0 до 1 на каждый выход. `camera.Shake(0.4)` добавляет травму, а она убывает на [Затухание](ref:camera.CameraShake2D.Decay) в секунду. Вид сдвигается не больше чем на [Макс. смещение](ref:camera.CameraShake2D.MaxOffset) и поворачивается не больше чем на [Макс. угол](ref:camera.CameraShake2D.MaxAngle), с множителем «травма в [Степени](ref:camera.CameraShake2D.Exponent)», поэтому слабые удары остаются едва заметными. Если на активной камере нет «Тряски камеры 2D», берутся значения по умолчанию.
Движение берётся из детерминированного шума, поэтому повтор трясётся так же. Тряска никогда не трогает трансформацию узла и случайные числа игры.
Травма складывается и убывает в реальном времени. При «Затухании» по умолчанию 1,5 удар силой 0,6 проходит за 0,4 секунды:
```aes run
package demo
import (
"aego/camera"
"aego/log"
)
script Hits {
var frames int
func Ready() {
camera.Shake(0.6)
log.Info("hit, trauma " + string(camera.Trauma()))
}
func Update(dt float) {
frames++
if frames % 6 == 0 && frames <= 30 {
log.Info("trauma " + string(camera.Trauma()))
}
if frames == 30 {
camera.Shake(0.5)
camera.Shake(0.8)
log.Info("two hits, capped at " + string(camera.Trauma()))
}
}
}
```
## Доступность
**Настройки → Доступность → Тряска экрана** масштабирует любую тряску; 0 выключает её. «Меньше движения» выключает тряску и убирает упреждение. Травма по-прежнему убывает, поэтому геймплей, который читает `camera.Trauma()`, не затронут.
---
id: camera/time
title: Время и повторы
---
# Время и повторы
[«Шкала времени»](ref:camera.VirtualCamera2D.TimeDomain) решает, как переходы и тряска активной камеры считают время. `unscaled`, значение по умолчанию, использует реальное время: стоп-кадр при ударе с масштабом времени 0 не замораживает камеру. `game` следует за масштабом времени и паузой.
Слежение всегда использует игровое время: когда игра на паузе или идёт по шагам, неподвижная цель держит камеру неподвижной.
Перемотка и повтор сохраняют активную камеру, перекрытия, зоны и всё, что идёт в игровом времени. После перехода к другому моменту переход в реальном времени сразу завершается, а тряска в реальном времени сохраняет свою травму.
---
id: camera/scripting
title: Скрипты
---
# Скрипты
import "aego/camera"
func OnCollisionEnter(other NodeRef, c physics.Contact) {
if c.Normal.Y < -0.5 && c.NormalImpulse > 8 {
camera.Shake(0.35)
}
}
func Boss() coroutine {
yield camera.BlendTo(BossCam, 1.5)
yield waitSeconds(3)
camera.Release(0)
}
| Функция | |
|---|---|
| `Active() NodeRef`, `ActiveOn(output) NodeRef` | виртуальная камера, которая управляет выходом |
| `BlendTo(camera, seconds) Blend` | сделать камеру активной поверх приоритетов и плавно перейти к ней; 0 берёт её «Время перехода» |
| `Cut(camera)` | то же без перехода |
| `Release(seconds) Blend` | вернуть главный выход приоритетам |
| `Shake(trauma)`, `ShakeOn(output, trauma)` | добавить травму |
| `Trauma() float` | травма главного выхода |
| `LogicalPose() Pose` | поза без тряски и привязки к пикселям |
| `RenderPose() Pose` | поза, с которой нарисован главный выход |
| `ScreenToWorld(p)`, `WorldToScreen(p)` | пересчёт по последнему нарисованному виду, в пикселях выхода |
У `Blend` есть `Done()`, `Running()`, `Stop()` и сигнал `Completed(finished bool)`; `yield` ждёт его. Методы компонентов: `VirtualCamera2D.IsActive()`, `CameraFollow2D.Snap()` и `CameraShake2D.Add(trauma)`.
Каждый выход хранит свою травму:
```aes run
package demo
import (
"aego/camera"
"aego/log"
)
script Outputs {
func Ready() {
camera.Shake(0.3)
camera.ShakeOn("map", 0.9)
log.Info("main " + string(camera.Trauma()))
log.Info("active camera is nil: " + string(camera.Active() == nil))
}
}
```
---
id: camera/editor
title: Инструменты редактора
---
# Инструменты редактора
Редактор рисует рамки камер, мёртвые зоны и зоны, а во время игры показывает состояние активной камеры.
## Маркеры и рамки
- Выберите виртуальную камеру, чтобы перетаскивать её границы, или зону, чтобы перетаскивать её область. Следящая камера показывает свою рамку, мёртвую зону и линию к цели. Каждое перетаскивание — один шаг отмены.
- **Камера → Рамки камер** включает и выключает рамки на панели «Сцена». Во время игры панель «Игра» тоже рисует мёртвую зону активной камеры, её границы и зоны.
## Инспектор во время игры
Виртуальная камера показывает, активна ли она, свой приоритет, ход перехода и травму. **Смотреть через камеру** переносит панель «Сцена» в её позу. У «Слежения камеры 2D» есть **Привязать к цели**.
## Профилирование и проблемы
- **Профилировщик → Камера** перечисляет все выходы с их активной виртуальной камерой, масштабом и ходом перехода.
- «Проблемы» показывают слежение и тряску без виртуальной камеры ([CAM001](ref:CAM001)), зоны без камеры ([CAM002](ref:CAM002)), пустые прямоугольники ([CAM003](ref:CAM003)) и слежение без цели ([CAM004](ref:CAM004)).
---
id: camera/go
title: Go
---
# Go
cams := sdk.CamerasOf(ctx)
cams.Shake("", 0.5)
if k, err := cams.BlendTo(bossCam, 1.5, false); err == nil {
cams.OnBlendCompleted(k, func(finished bool) { ... })
}
У `Service` есть `Active`, `BlendTo`, `Release`, `Shake`, `Trauma`, `Logical`, `Render`, `View` и `Snap`; все они принимают имя выхода, `""` — главный выход.
Модуль публикует контракт `camera2d.adjust`; `render2d.cameras` просит его подправить вид каждой «Камеры 2D». Система `camera.update` (PostUpdate, работает и на паузе) выбирает камеры, продвигает переходы и зоны и гасит травму. Слежение и итоговая поза вычисляются при построении вида, один раз на выход и кадр. Модуль может масштабировать тряску, предоставив `camera2d.accessibility` с идентификаторами своих настроек.