Camera
API Camera позволяет читать главную камеру сцены и создавать дополнительные камеры. Дополнительная камера рендерит изображение в текстуру: её можно вывести через UI или ImGui.
Весь раздел доступен только в клиентской Lua-части. В server.lua Reflex-модуля глобальный объект Cameras равен nil.
Как камера обрабатывается игрой
Заголовок раздела «Как камера обрабатывается игрой»Cameras.Main оборачивает реальную активную камеру игрового клиента. Setter-ы сразу меняют её компонент, но контроллер персонажа и другие системы камеры могут записать своё состояние на следующем кадре.
CreateCamera() регистрирует отдельную клиентскую камеру и создаёт для неё render texture. Пока камера активна, renderer обновляет OutputTexture; SetActive(false) останавливает новые кадры, а RemoveCamera() удаляет созданный ресурс. Ни один из этих вызовов сам не добавляет текстуру в HUD.
Главное
Заголовок раздела «Главное»Cameras.Mainвозвращает главную камеру и доступен только для чтения.Cameras:CreateCamera()создаёт пользовательскую камеру.IsMainCameraиOutputTexture— свойства только для чтения.SetActive(false)останавливает обновлениеOutputTexture, сохраняя последний кадр.- Пользовательская камера не заменяет основной вид автоматически: её
OutputTextureнужно вывести на экран.
Где появляется результат
Заголовок раздела «Где появляется результат»| Действие | Что меняется |
|---|---|
Изменение Cameras.Main |
Сразу меняет основной игровой вид. Игра может перезаписать значения в следующем кадре. |
| Создание пользовательской камеры | Само по себе ничего не добавляет на экран. Изображение доступно только через OutputTexture. |
SetActive(false) |
Замораживает обновление текстуры, но не скрывает уже выведенное изображение. |
WorldToViewportPoint() |
Только вычисляет экранное положение точки и ничего не рисует. |
Чтобы показать пользовательскую камеру, передайте OutputTexture в ImGui или элемент UI. Размер текстуры и её размер на экране задаются независимо.
Полный пример
Заголовок раздела «Полный пример»Пример создаёт превью 320 × 180 в левом верхнем углу. Дополнительная камера следует за главной, но находится на два метра выше.
local PreviewCamera = Cameras:CreateCamera()
if PreviewCamera == nil then print("[Camera example] Camera limit reached")else PreviewCamera:SetRenderSize(320, 180) PreviewCamera.Aspect = 320 / 180 PreviewCamera.Fov = 60 PreviewCamera:SetActive(true)
Scheduler:OnFrame(function() local mainCamera = Cameras.Main PreviewCamera.Position = mainCamera.Position + Vector3.new(0, 2, 0) PreviewCamera.Rotation = mainCamera.Rotation
local texture = PreviewCamera.OutputTexture if texture ~= nil then ImGui:DrawTexture(texture, Rect.new(20, 20, 320, 180)) end end)endImGui работает в immediate mode, поэтому DrawTexture вызывается каждый кадр. Сама камера при этом создаётся только один раз.
Объект главной или пользовательской камеры. Напрямую не создаётся: используйте Cameras.Main или Cameras:CreateCamera().
Свойства
Заголовок раздела «Свойства»| Свойство | Тип | Доступ | Описание |
|---|---|---|---|
Aspect |
number |
get/set |
Соотношение ширины изображения к высоте. |
FarClipPlane |
number |
get/set |
Дальняя плоскость отсечения в метрах. |
Fov |
number |
get/set |
Вертикальный угол обзора в градусах. |
IsMainCamera |
bool |
get |
true только для главной камеры сцены. |
IsOrthographic |
bool |
get/set |
Включена ли ортографическая проекция. |
NearClipPlane |
number |
get/set |
Ближняя плоскость отсечения в метрах. |
OrthographicSize |
number |
get/set |
Размер ортографической камеры. Используется при IsOrthographic = true. |
OutputTexture |
Texture | nil |
get |
Текстура пользовательской камеры. У главной камеры возвращает nil. |
Position |
Vector3 |
get/set |
Позиция камеры в мировых координатах. |
Rotation |
Quaternion |
get/set |
Вращение камеры в мировых координатах. |
SetActive
Заголовок раздела «SetActive»camera:SetActive(value: bool)Включает или останавливает рендер пользовательской камеры.
| Аргумент | Тип | Описание |
|---|---|---|
value |
bool |
true — обновлять изображение; false — остановить обновление. |
При false объект камеры и OutputTexture сохраняются, а в текстуре остаётся последний отрисованный кадр. Повторный вызов с true возобновляет рендер.
SetRenderSize
Заголовок раздела «SetRenderSize»camera:SetRenderSize(width: int, height: int)Задаёт размер OutputTexture пользовательской камеры в пикселях.
| Аргумент | Тип | Описание |
|---|---|---|
width |
int |
Ширина текстуры. |
height |
int |
Высота текстуры. |
После camera:SetRenderSize(320, 180) свойства camera.OutputTexture.width и camera.OutputTexture.height возвращают 320 и 180.
SetRenderSize не меняет Aspect автоматически. Обычно оба значения задаются вместе:
camera:SetRenderSize(320, 180)camera.Aspect = 320 / 180WorldToViewportPoint
Заголовок раздела «WorldToViewportPoint»camera:WorldToViewportPoint(worldPosition: Vector3): Vector3Преобразует мировую позицию в координаты viewport:
(0, 0)— левый нижний угол;(1, 1)— правый верхний угол;z— расстояние от камеры в метрах;- отрицательный
zозначает, что точка находится позади камеры.
Для камеры в начале координат с Fov = 90, Aspect = 1 и нулевым вращением получены следующие значения:
| Мировая позиция | Результат |
|---|---|
(0, 0, 10) |
(0.5, 0.5, 10) — центр экрана |
(10, 0, 10) |
(1, 0.5, 10) — правый край |
(0, 10, 10) |
(0.5, 1, 10) — верхний край |
(0, 0, -10) |
(0.5, 0.5, -10) — позади камеры |
Cameras
Заголовок раздела «Cameras»Глобальный клиентский API для получения и создания камер.
local mainCamera = Cameras.MainВозвращает главную камеру сцены. Само свойство Main доступно только для чтения.
CreateCamera
Заголовок раздела «CreateCamera»local camera = Cameras:CreateCamera()Создаёт и возвращает пользовательскую камеру. Перед использованием результата рекомендуется проверить его на nil.
RemoveCamera
Заголовок раздела «RemoveCamera»Cameras:RemoveCamera(camera)Удаляет ранее созданную пользовательскую камеру. После удаления сохранённую ссылку использовать нельзя.
camera:SetActive(false)Cameras:RemoveCamera(camera)camera = nilЧастые ошибки
Заголовок раздела «Частые ошибки»Запись в getter-only свойства
Заголовок раздела «Запись в getter-only свойства»Следующие операции завершаются Lua-ошибкой доступа:
Cameras.Main = cameracamera.IsMainCamera = truecamera.OutputTexture = textureОжидание автоматического переключения вида
Заголовок раздела «Ожидание автоматического переключения вида»camera:SetActive(true) запускает рендер дополнительной камеры, но не заменяет изображение главной камеры. Покажите camera.OutputTexture через UI-элемент или ImGui:DrawTexture().
Точка позади камеры
Заголовок раздела «Точка позади камеры»Проверки только x и y недостаточно. Перед отрисовкой маркера убедитесь, что результат WorldToViewportPoint() имеет z > 0.