--- title: Компонент Camera brief: В данном руководстве описаны функциональные возможности компонента Camera в Defold. --- # Компонент Camera В Defold камера --- это компонент, который изменяет область обзора и проекцию игрового мира. Компонент Camera лишь поверхностно определяет перспективную или ортографическую камеры, которая предоставляет рендер-скрипту матрицу вида и проекции. Перспективная камера обычно используется для 3D-игр, ортографическая камера --- для 2D. Если требуются расширенные возможности, такие как преследование, зумирование, дрожание и т.д., придется реализовать их самостоятельно (см. раздел ниже [сторонние решения для камер](https://www.defold.com/manuals/camera/#third-party-camera-solutions)). ## Создание камеры Чтобы создать камеру, кликните ПКМ на игровом объекте и выберите Add Component ▸ Camera. Можно также создать файл компонента в иерархии проекта и добавить этот файл к игровому объекту. ![create camera component](images/camera/create.png){srcset="images/camera/create@2x.png 2x"} Компонент Camera имеет следующие свойства, определяющие усеченную пирамиду видимости, или *фрустум* (только для перспективной камеры): ![camera settings](images/camera/settings.png){srcset="images/camera/settings@2x.png 2x"} Id : Идентификатор компонента Aspect Ratio : (**Только для перспективной камеры**) --- Соотношение между шириной и высотой фрустума. 1.0 предполагает квадратичное представление. 1,33 подходит для формата 4:3, например, 1024x768. 1.78 подходит для формата 16:9. Данное свойство игнорируется, если отмечена опция *Auto Aspect Ratio*. Fov : (**Только для перспективной камеры**) --- Поле зрения камеры по *вертикали*, выраженное в _радианах_. Чем шире поле зрения, тем больше камера видит. Обратите внимание, что текущее значение по умолчанию (45) вводит в заблуждение. Для поля зрения в 45 градусов измените значение на 0.785 (`π / 4`). Near Z : (**Только для перспективной камеры**) --- Z-значение ближней плоскости отсечения. Far Z : (**Только для перспективной камеры**) --- Z-значение дельней плоскости отсечения. Auto Aspect Ratio : (**Только для перспективной камеры**) --- Если опция отмечена, камера будет вычислять соотношение сторон автоматически. ## Использование камеры Чтобы активировать камеру и передать ее матрицы вида и проекции в рендер-скрипт, нужно вызвать функцию `camera.acquire_focus` или отправить компоненту сообщение acquire_camera_focus: ```lua camera.acquire_focus("#camera") ``` или ```lua msg.post("#camera", "acquire_camera_focus") ``` В каждом кадре компонент 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. Сообщение, переданное от компонента камеры, включает матрицу вида и матрицу проекции. ### Панорамирование камеры Панорамирование/перемещение камеры по игровому миру осуществляется путем перемещения игрового объекта, к которому присоединен компонент камеры. Компонент Camera автоматически отправляет обновленную матрицу вида согласно текущему положению камеры по осям X и Y. ### Зумирование камеры Увеличение и уменьшение масштаба при использовании перспективной камеры осуществляется путем перемещения игрового объекта, к которому прикреплена камера, вдоль оси Z. Компонент камеры автоматически отправляет обновленную матрицу вида согласно текущему положению камеры по оси Z. Увеличивать и уменьшать масштаб при использовании ортографической камеры можно, только если тип проекции установлен в `Fixed`, при этом масштаб изменяется путем отправки рендер-скрипту сообщения с требуемым уровнем масштабирования: ```Lua msg.post("@render:", "use_fixed_projection", { zoom = 2, near = -1, far = 1 }) ``` ### Следование за игровым объектом Можно заставить камеру следовать за игровым объектом. Для этого достаточно создать игровой объект с прикрепленным к нему компонентом Camera и разместить его в качестве дочернего по отношению к тому объекту, за которым необходимо следовать: ![follow game object](images/camera/follow.png) Альтернативный способ заключается в обновлении положения игрового объекта, к которому прикреплен компонент Camera, каждый кадр по мере перемещения игрового объекта, за которым нужно следить. ### Преобразование экранных координат в мировые При панорамировании, масштабировании или изменении проекции камеры с ортографической проекцией типа Stretch по умолчанию координаты мыши, предоставленные в функции жизненного цикла on_input(), больше не будут соответствовать мировым координатам игровых объектов. Необходимо вручную учесть изменение вида или проекции. Преобразование координат мыши/экрана в мировые координаты из стандартного рендер-скрипта выполняется следующим образом: ::: sidenote [Сторонние решения для камер, упомянутые в данном руководстве](/manuals/camera/#third-party-camera-solutions) предоставляют функции для преобразования в экранные координаты и обратно. ::: ```Lua -- builtins/render/default.render_script -- local function screen_to_world(x, y, z) local inv = vmath.inv(self.projection * self.view) x = (2 * x / render.get_width()) - 1 y = (2 * y / render.get_height()) - 1 z = (2 * z) - 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 local z1 = x * inv.m20 + y * inv.m21 + z * inv.m22 + inv.m23 return x1, y1, z1 end ``` ## Проекции Компонент Camera передает рендер-скрипту перспективную проекцию. Это хорошо подходит для 3D-игр. Для 2D-игр зачастую требуется рендерить сцену с *ортографической проекцией*. Это означает, что вид камеры определяется не фрустумом, а фреймом. Ортографическая проекция нереалистична, поскольку она не искажает размер объектов в зависимости от расстояния до них. Объект, находящийся на расстоянии в 1000 единиц, будет отображаться в том же размере, что и объект прямо перед камерой. ![projections](images/camera/projections.png){srcset="images/camera/projections@2x.png 2x"} ### Ортографическая проекция (2D) Для использования ортографической проекции матрица проекции, передаваемая компонентом Camera, игнорируется, и вместо этого она создается самостоятельно в рендер-скрипте. Рендер-скрипт по умолчанию поддерживает три ортографические проекции: `Stretch`, `Fixed` и `Fixed Fit`. Чтобы выбрать, какую из них использовать, достаточно послать сообщение в рендер-скрипт: ```lua msg.post("@render:", "use_fixed_fit_projection", { near = -1, far = 1 }) ``` ::: important Следует отметить, что ближняя и дальняя плоскости также указываются в сообщении. Ближняя и дальняя плоскости, заданные в свойствах камеры, используются только для перспективной проекции. ::: ::: important При ортографической проекции представление будет расположено так, что левый нижний угол отрендеренной части экрана будет соответствовать положению игрового объекта, к которому прикреплен компонент Camera. ::: Подробнее о рендер-скрипте и о том, как изменить тип используемой ортографической проекции, можно узнать в [руководстве по рендерингу](/manuals/render/#default-view-projection). ### Перспективная проекция (3D) Чтобы использовать перспективную проекцию, необходимо использовать как вид, так и проекцию, предоставляемые камерой. Рендер-скрипт должен использовать проекцию, исходящую от камеры, отправленную ему в сообщении: ```lua msg.post("@render:", "use_camera_projection") ``` За подробностями о рендер-скрипте обращайтесь к [руководстве по рендерингу](/manuals/render/#perspective-projection). ## Сторонние решения для камер Существует несколько библиотечных решений, реализующих общие функции камеры, такие как следование за игровым объектом, преобразование координат экрана в мировые и так далее. Они доступны на портале ассетов сообщества Defold: - [Rendercam](https://defold.com/assets/rendercam/) (2D & 3D), автор Ross Grams. - [Ortographic camera](https://defold.com/assets/orthographic/) (2D only), автор Björn Ritzl.