---
title: Компонент Camera
brief: В данном руководстве описаны функциональные возможности компонента Camera в Defold.
---
# Камеры
Камера в Defold — это компонент, который изменяет область просмотра (viewport) и проекцию игрового мира. Компонент камеры определяет базовую перспективную или ортографическую камеру, которая предоставляет матрицы вида и проекции в рендер-скрипт.
Перспективная камера обычно используется для 3D-игр, где вид камеры и размер и перспектива объектов основаны на усечённой пирамиде (view frustum) и расстоянии и угле обзора от камеры до объектов в игре.
Для 2D-игр часто предпочтительно использовать ортографическую проекцию. Это означает, что вид камеры больше не определяется усечённой пирамидой, а ограничен параллелепипедом. Ортографическая проекция нереалистична, так как не изменяет размер объектов в зависимости от расстояния. Объект на расстоянии 1000 единиц будет отображаться того же размера, что и объект прямо перед камерой.

## Создание камеры
Чтобы создать камеру, кликните правой кнопкой мыши по игровому объекту и выберите Add Component ▸ Camera. Также можно создать файл компонента камеры в иерархии проекта и добавить его к игровому объекту.

Компонент камеры имеет следующие свойства, определяющие *усечённую пирамиду* камеры:

Id
: Идентификатор компонента
Aspect Ratio
: (**Только для перспективной камеры**) — соотношение ширины и высоты усечённой пирамиды. 1.0 означает квадратный вид. 1.33 подходит для соотношения 4:3, например 1024x768. 1.78 — для 16:9. Это значение игнорируется, если включён *Auto Aspect Ratio*.
Fov
: (**Только для перспективной камеры**) — *вертикальный* угол обзора камеры в _радианах_. Чем шире угол обзора, тем больше камера видит.
Near Z
: Z-значение ближней плоскости отсечения.
Far Z
: Z-значение дальней плоскости отсечения.
Auto Aspect Ratio
: (**Только для перспективной камеры**) — если включено, камера автоматически вычисляет соотношение сторон.
Orthographic Projection
: Включите, чтобы использовать ортографическую проекцию (см. ниже).
Orthographic Zoom
: (**Только для ортографической камеры**) — масштаб ортографической проекции (> 1 = приближение, < 1 = отдаление).
Orthographic Mode
: (**Только для ортографической камеры**) — управляет тем, как ортографическая камера определяет зум относительно размера окна и ваших значений дизайна (`game.project` → `display.width/height`).
- `Fixed` (постоянный зум): используется текущее значение `Orthographic Zoom`.
- `Auto Fit` (вписать): автоматически подбирает зум так, чтобы вся дизайн-область помещалась в окно. Возможен дополнительный контент по бокам/сверху/снизу.
- `Auto Cover` (заполнить): автоматически подбирает зум так, чтобы дизайн-область заполняла окно целиком. Возможна обрезка по бокам/сверху/снизу.
Доступно только при включённой `Orthographic Projection`.
## Использование камеры
Все камеры по умолчанию включены и обновляются каждый кадр, а Lua-модуль `camera` доступен во всех скриптовых контекстах. Начиная с Defold 1.8.1, больше не нужно явно включать камеру через отправку сообщения `acquire_camera_focus` компоненту камеры. Старые сообщения acquire и release всё ещё поддерживаются, но рекомендуется использовать сообщения `enable` и `disable`, как для любого другого компонента, который нужно включать или выключать:
```lua
msg.post("#camera", "disable")
msg.post("#camera", "enable")
```
Чтобы получить список всех доступных камер, используйте функцию `camera.get_cameras()`:
```lua
-- Внимание: вызовы render доступны только в рендер-скрипте.
-- camera.get_cameras() можно использовать везде,
-- но render.set_camera — только в рендер-скрипте.
for k,v in pairs(camera.get_cameras()) do
-- таблица camera содержит URL всех камер
render.set_camera(v)
-- здесь выполняется рендеринг — всё, что использует материалы с
-- матрицами вида и проекции, будет использовать матрицы этой камеры.
end
-- чтобы отключить камеру, передайте nil (или вызовите без аргументов) в render.set_camera.
-- после этого все вызовы рендеринга будут использовать матрицы вида и проекции,
-- заданные напрямую в рендер-контексте через render.set_view и render.set_projection
render.set_camera()
```
Модуль `camera` содержит множество функций для управления камерой. Вот несколько из них, полный список доступен в [API документации](/ref/camera/):
```lua
camera.get_aspect_ratio(camera) -- получить соотношение сторон
camera.get_far_z(camera) -- получить дальнюю плоскость отсечения
camera.get_fov(camera) -- получить угол обзора
camera.get_orthographic_mode(camera) -- получить ортографический режим (одно из camera.ORTHO_MODE_*)
camera.set_aspect_ratio(camera, ratio) -- установить соотношение сторон
camera.set_far_z(camera, far_z) -- установить дальнюю плоскость отсечения
camera.set_near_z(camera, near_z) -- установить ближнюю плоскость отсечения
camera.set_orthographic_mode(camera, camera.ORTHO_MODE_AUTO_FIT) -- установить ортографический режим
... и другие
```
Камера идентифицируется URL, который представляет полный путь к компоненту в сцене, включая коллекцию, игровой объект и id компонента. В примере используйте URL `/go#camera` для доступа к компоненту камеры из той же коллекции, и `main:/go#camera` для доступа к камере из другой коллекции или рендер-скрипта.

```lua
-- Доступ к камере из скрипта в той же коллекции:
camera.get_fov("/go#camera")
-- Доступ к камере из скрипта в другой коллекции:
camera.get_fov("main:/go#camera")
-- Доступ к камере из рендер-скрипта:
render.set_camera("main:/go#camera")
```
Каждый кадр компонент камеры с текущим фокусом камеры отправляет сообщение `set_view_projection` на сокет "@render":
```lua
-- builtins/render/default.render_script
--
function on_message(self, message_id, message)
if message_id == hash("set_view_projection") then
self.view = message.view -- [1]
self.projection = message.projection
end
end
```
1. Сообщение от компонента камеры содержит матрицу вида и матрицу проекции.
Компонент камеры предоставляет рендер-скрипту матрицу проекции перспективной или ортографической камеры в зависимости от свойства *Orthographic Projection*. Матрица проекции учитывает ближнюю и дальнюю плоскости отсечения, угол обзора и соотношение сторон камеры.
Матрица вида определяет позицию и ориентацию камеры. Камера с *Orthographic Projection* центрирует вид на позиции игрового объекта, к которому прикреплён компонент камеры, тогда как камера с *Perspective Projection* располагает нижний левый угол вида на позиции игрового объекта.
### Рендер-скрипт
Начиная с Defold 1.9.6, при использовании дефолтного рендер-скрипта Defold автоматически устанавливает последнюю включённую камеру для рендеринга. Ранее требовалось явно отправлять сообщение `use_camera_projection` рендереру, чтобы уведомить его об использовании матриц камеры. Сейчас это не обязательно, но для обратной совместимости можно продолжать использовать.
Также можно явно задать конкретную камеру для рендеринга в рендер-скрипте. Это полезно, например, в многопользовательских играх для точного контроля, какая камера используется.
```lua
-- render.set_camera автоматически применит матрицы вида и проекции
-- для всего рендеринга, пока не будет вызван render.set_camera() без аргументов.
render.set_camera("main:/my_go#camera")
```
Чтобы проверить, включена ли камера, используйте функцию `get_enabled` из [Camera API](https://defold.com/ref/alpha/camera/#camera.get_enabled:camera):
```lua
if camera.get_enabled("main:/my_go#camera") then
-- камера включена, используем её для рендеринга
render.set_camera("main:/my_go#camera")
end
```
::: sidenote
Чтобы использовать `set_camera` вместе с отсечением по усечённой пирамиде (frustum culling), передайте опцию:
`render.set_camera("main:/my_go#camera", {use_frustum = true})`
:::
### Панорамирование камеры
Перемещайте камеру по игровому миру, перемещая игровой объект, к которому прикреплён компонент камеры. Компонент автоматически отправит обновлённую матрицу вида на основе текущих координат по осям X и Y.
### Масштабирование камеры
Для перспективной камеры масштабирование происходит перемещением игрового объекта по оси Z. Компонент камеры автоматически обновит матрицу вида с учётом текущей позиции по Z.
Для ортографической камеры масштабирование выполняется изменением свойства *Orthographic Zoom*:
```lua
go.set("#camera", "orthographic_zoom", 2)
```
Также для ортографической камеры можно выбрать способ определения зума с помощью параметра `Orthographic Mode` или из кода:
```lua
-- текущий режим (одно из: camera.ORTHO_MODE_FIXED, _AUTO_FIT, _AUTO_COVER)
local mode = camera.get_orthographic_mode("#camera")
-- включить режим "вписать" (contain), чтобы дизайн-область всегда полностью помещалась в окно
camera.set_orthographic_mode("#camera", camera.ORTHO_MODE_AUTO_FIT)
-- включить режим "заполнить" (cover), чтобы окно всегда было заполнено
-- camera.set_orthographic_mode("#camera", camera.ORTHO_MODE_AUTO_COVER)
-- вернуть "фиксированный" режим и управлять масштабом вручную через orthographic_zoom
-- camera.set_orthographic_mode("#camera", camera.ORTHO_MODE_FIXED)
```
### Адаптивный зум
Адаптивный зум — это изменение значения зума камеры при изменении разрешения экрана относительно первоначального разрешения, заданного в *game.project*.
Два распространённых подхода к адаптивному зуму:
1. Максимальный зум — вычисляется так, чтобы контент, покрываемый изначальным разрешением, заполнял и выходил за границы экрана, возможно, скрывая часть контента по бокам или сверху/снизу.
2. Минимальный зум — вычисляется так, чтобы контент изначального разрешения полностью помещался в экран, возможно, показывая дополнительный контент по бокам или сверху/снизу.
Пример:
```lua
local DISPLAY_WIDTH = sys.get_config_int("display.width")
local DISPLAY_HEIGHT = sys.get_config_int("display.height")
function init(self)
local initial_zoom = go.get("#camera", "orthographic_zoom")
local display_scale = window.get_display_scale()
window.set_listener(function(self, event, data)
if event == window.WINDOW_EVENT_RESIZED then
local window_width = data.width
local window_height = data.height
local design_width = DISPLAY_WIDTH / initial_zoom
local design_height = DISPLAY_HEIGHT / initial_zoom
-- max zoom: контент изначального разрешения заполнит и выйдет за границы экрана
local zoom = math.max(window_width / design_width, window_height / design_height) / display_scale
-- min zoom: контент изначального разрешения полностью поместится в экран
--local zoom = math.min(window_width / design_width, window_height / design_height) / display_scale
go.set("#camera", "orthographic_zoom", zoom)
end
end)
end
```
Полный пример адаптивного зума доступен в [этом примерном проекте](https://github.com/defold/sample-adaptive-zoom).
Примечание: Для ортографической камеры типичное поведение «вписать/заполнить» можно получить без пользовательского кода, установив `Orthographic Mode` в `Auto Fit` (вписать) или `Auto Cover` (заполнить). В этих режимах эффективный зум рассчитывается автоматически на основе размера окна и заданного разрешения дизайна.
### Следование за игровым объектом
Камера может следовать за игровым объектом, если сделать игровой объект с компонентом камеры дочерним по отношению к объекту, за которым нужно следить:

Альтернативный способ — обновлять позицию игрового объекта с компонентом камеры каждый кадр в соответствии с позицией объекта, за которым следят.
### Преобразование мыши в мировые координаты
Когда камера смещена, масштабирована или изменена проекция с дефолтной ортографической Stretch-проекцией, координаты мыши, получаемые в функции `on_input()`, больше не совпадают с мировыми координатами игровых объектов. Нужно вручную учитывать изменения вида и проекции. Код для преобразования экранных координат в мировые выглядит так:
```lua
--- Преобразует экранные координаты в мировые с учётом
-- вида и проекции конкретной камеры
-- @param camera URL камеры для преобразования
-- @param screen_x экранная координата X
-- @param screen_y экранная координата Y
-- @param z опциональный Z для преобразования, по умолчанию 0
-- @return world_x мировая координата X
-- @return world_y мировая координата Y
-- @return world_z мировая координата Z
function M.screen_to_world(camera, screen_x, screen_y, z)
local projection = go.get(camera, "projection")
local view = go.get(camera, "view")
local w, h = window.get_size()
-- https://defold.com/manuals/camera/#converting-mouse-to-world-coordinates
local inv = vmath.inv(projection * view)
local x = (2 * screen_x / w) - 1
local y = (2 * screen_y / h) - 1
local x1 = x * inv.m00 + y * inv.m01 + z * inv.m02 + inv.m03
local y1 = x * inv.m10 + y * inv.m11 + z * inv.m12 + inv.m13
return x1, y1, z or 0
end
```
Имейте в виду, что значения `action.screen_x` и `action.screen_y` из `on_input()` должны использоваться как аргументы для этой функции. На странице [Примеры](https://defold.com/examples/render/screen_to_world/) показано использование преобразования экранных координат в мировые. Также есть [примерный проект](https://github.com/defold/sample-screen-to-world-coordinates/) с демонстрацией этого процесса.
::: sidenote
[Сторонние решения для камеры](/manuals/camera/#third-party-camera-solutions) предоставляют функции для преобразования координат между экраном и миром.
:::
## Манипуляции во время выполнения
Камеры можно изменять из кода с помощью различных сообщений и свойств (подробности в [API документации](/ref/camera/)).
Компонент камеры имеет следующие свойства, которые можно читать и изменять через `go.get()` и `go.set()`:
`fov`
: Угол обзора камеры (`number`).
`near_z`
: Ближняя плоскость отсечения (`number`).
`far_z`
: Дальняя плоскость отсечения (`number`).
`orthographic_zoom`
: Масштаб ортографической камеры (`number`).
`aspect_ratio`
: Соотношение ширины и высоты усечённой пирамиды. Используется при вычислении проекции перспективной камеры. (`number`).
`view`
: Вычисленная матрица вида камеры. ТОЛЬКО ДЛЯ ЧТЕНИЯ. (`matrix4`).
`projection`
: Вычисленная матрица проекции камеры. ТОЛЬКО ДЛЯ ЧТЕНИЯ. (`matrix4`).
## Сторонние решения для камеры
Существуют решения сообщества, которые реализуют распространённые функции, такие как тряска экрана, следование за объектами, преобразование экранных координат в мировые и многое другое. Их можно скачать с портала Defold Asset Portal:
- [Orthographic camera](https://defold.com/assets/orthographic/) (только 2D) от Бьёрна Ритцля.
- [Defold Rendy](https://defold.com/assets/defold-rendy/) (2D и 3D) от Клейтона Ковальски.