Camera System
Пакет управления ортографическими камерами: позиционирование, фокус на объектах, ограничение перемещения границами.
Assembly: ru.vortex.unity.camera
Namespace: Vortex.Unity.Camera
Слой: 2 (Unity)
Архитектура
CameraBus (шина)
├── Controllers (static, extension methods)
│ ├── CameraMoveController — покадровое обновление позиции и цели
│ ├── CameraFocusController — управление группами фокуса
│ └── CameraBordersController — управление границами перемещения
├── Model
│ ├── CameraModel — реактивная модель данных камеры
│ └── CameraFocusTarget — группа объектов фокуса
└── View
├── CameraDataStorage — MonoBehaviour-хранилище модели (IDataStorage)
└── Handlers
├── CameraHandler — базовый класс хендлеров камеры
├── CameraMoveHandler — плавное приведение камеры к цели
├── FocusHandler — декларативная привязка фокуса
└── BordersHandler — декларативная привязка границ
Поток данных
CameraDataStorageрегистрируется вCameraBusприAwakeCameraMoveControllerподписывается на регистрацию, захватывает ownership надPosition/Target- Каждый
FixedUpdateконтроллер обновляет позицию и цель по данным фокуса CameraMoveHandler(View) получаетOnUpdateData, вычисляет итоговую позицию с учётом границ и плавно перемещает камеру
CameraBus
Статическая шина регистрации камер. Ключ — gameObject.name.
// Регистрация (автоматически в CameraDataStorage.Awake)
CameraBus.Registration(storage);
// Получение
var cam = CameraBus.Get("Map Camera"); // с LogError при отсутствии
if (CameraBus.TryGet("Map Camera", out var cam)) { } // без ошибки
var any = CameraBus.GetAny(); // первая доступная (null если пусто)
События:
OnRegistration— камера зарегистрированаOnRemove— камера снята с регистрации
CameraModel
Реактивная модель данных камеры. Реализует IReactiveData.
| Свойство | Тип | Описание |
|---|---|---|
CameraRect |
Vector2Data |
Размер видимой области в мировых единицах (width, height) |
Position |
Vector2Data |
Текущая позиция камеры |
Target |
Vector2Data |
Целевая позиция (центр группы фокуса) |
FocusedObjects |
IReadOnlyList<CameraFocusTarget> |
Стек групп фокуса, приоритет у последней |
Borders |
IReadOnlyList<RectTransform> |
Стек границ, активна последняя |
IsBordered |
bool |
Включены ли ограничения (default: true) |
Ownership: Position и Target принадлежат CameraMoveController — изменение только через контроллер.
Контроллеры
CameraMoveController
Статический контроллер покадрового обновления. Работает через TimeController.AddCallback (FixedUpdate).
Логика:
- Без фокуса:
Positionследует заtransform.position(камера управляется извне) - С фокусом:
transform.positionзадаётся изPosition(камера управляется моделью) Targetвсегда вычисляется как центр масс последней группы фокуса
// Extension method для установки позиции из View
data.SetPosition(new Vector2(1, 2));
CameraFocusController
Extension methods на CameraDataStorage для управления фокусом.
var cam = CameraBus.Get("Map Camera");
// Добавить объект в текущую группу (создаст группу если нет)
cam.AddInFocus(transform);
cam.AddInFocus(transforms); // ICollection<Transform>
// Заменить фокус новой группой
cam.SetNewFocusGroup(transform);
cam.SetNewFocusGroup(transforms);
// Удалить
cam.RemoveLastFocusGroup(); // удалить последнюю группу
cam.RemoveTargetFromFocus(transform); // удалить объект из всех групп
cam.ResetFocus(); // очистить все группы
Стек фокуса: группы работают по принципу LIFO. Камера центрируется на последней группе. При удалении последней — фокус возвращается к предыдущей.
CameraBordersController
Extension methods на CameraModel для управления границами.
// Добавить/удалить границу (RectTransform)
camera.Data.AddBorder(rectTransform);
camera.Data.RemoveBorder(rectTransform);
camera.Data.ClearBorders();
Границы работают аналогично фокусу — стек, активна последняя.
View
CameraDataStorage
MonoBehaviour-компонент камеры. Реализует IDataStorage для совместимости с DataStorageView<T>.
- Автоматически регистрируется/снимается в
CameraBus - Обновляет
CameraRectпри измененииorthographicSize RequireComponent(Camera)
CameraHandler
Базовый абстрактный класс для хендлеров, привязывающихся к камере по имени. Автоматически подписывается на CameraBus и переподключается при регистрации/удалении камер.
public class MyHandler : CameraHandler
{
protected override void SetData()
{
// Camera доступна, привязать данные
}
protected override void RemoveData()
{
// Отвязать данные
}
}
Настройки в Inspector:
cameraName— имя GameObject камерыuseAnyIfNotFoundKey— fallback на первую доступную камеру
CameraMoveHandler
Плавное приведение камеры к целевой позиции с учётом границ. Наследует DataStorageView<CameraModel>.
| Параметр | Диапазон | Default | Описание |
|---|---|---|---|
easeDuration |
0–3 сек | 1 | Время анимации при дальнем перемещении |
easeType |
EaseType | Linear | Функция плавности |
followingRange |
0–30 | 5 | Радиус мгновенного следования |
Логика:
- Если расстояние до цели <=
followingRange— мгновенное перемещение - Если дальше — плавная анимация через
AsyncTween - Позиция ограничивается активной границей (
Borders[^1]) с учётом размера камеры
FocusHandler
Декларативная привязка transform к фокусу камеры. OnEnable добавляет, OnDisable удаляет.
Режимы (FocusMode):
AddToFocus— добавить в текущую группуNewFocus— создать новую группу (заменить фокус)
BordersHandler
Декларативная привязка RectTransform как границы камеры. SetData добавляет, RemoveData удаляет.
Настройка сцены
Scene
├── Map Camera # GameObject с Camera
│ ├── CameraDataStorage # хранилище модели
│ └── CameraMoveHandler # плавное следование
│ source → Map Camera (CameraDataStorage)
├── Map
│ ├── Borders # RectTransform зоны перемещения
│ │ └── BordersHandler # cameraName = "Map Camera"
│ └── Objects
│ └── Player
│ └── FocusHandler # cameraName = "Map Camera"
Граничные случаи
- Камера зарегистрирована позже хендлера:
CameraHandlerподписан наCameraBus.OnRegistrationи автоматически подхватит камеру - Нет фокуса: камера не управляется моделью,
transform.positionчитается как есть - Границы меньше камеры:
Rectс отрицательным размером,Clampсхлопнет позицию в центр границ - Несколько камер: каждая независимо регистрируется в
CameraBusпо имени GameObject