14 KiB
2D-разработка в Forma
2D и 3D используют одну иерархию Babylon.js и обычный Transform с X/Y/Z. Спрайт — текстурированный прямоугольник в плоскости XY. Его можно разместить рядом с 3D-моделью, вложить в группу и показать перспективной или ортографической камерой.
Rapier2D 0.20.0 считает физику по X/Y и вращение вокруг Z. Rapier3D 0.20.0 продолжает обслуживать 3D-компоненты. Миры независимы: Collider2D взаимодействует с Collider2D независимо от визуальной глубины Z, но не с 3D Collider. Оба работают с фиксированным шагом 1/60 секунды; Z у физического 2D-объекта сохраняется.
Быстрый старт
В меню имени проекта выберите Новый проект → 2D Платформер. Шаблон содержит оригинальный небольшой атлас, анимации idle/run/jump, персонажа, карту тайлов, динамический ящик, одностороннюю платформу, камеру и декоративный 3D-куб.
Play запускает сцену. WASD/стрелки перемещают персонажа, пробел выполняет прыжок. В самостоятельном плеере есть сенсорный джойстик и кнопка прыжка. Stop возвращает исходное состояние. Шаблон — пример и точка старта; обычный новый проект по-прежнему пустой.
Для чистой сцены используйте Пустой 2D-проект или + 2D возле списка сцен. Кнопка 2D · XY / 3D переключает вид редактора, сохраняя общую сцену. Режим сцены сохраняется в её настройках и определяет камеру игры при отсутствии явно добавленной камеры.
Спрайты и анимация
- Нажмите Импорт спрайтов и выберите PNG, JPEG или WebP. PNG/WebP подходят для прозрачности. Лимит: 25 МБ, до 16384×16384 пикселей.
- В редакторе спрайтов задайте Pixels Per Unit. Например, 16 PPU превращают кадр 16×16 в квадрат 1×1 единицу сцены.
- Нарежьте атлас по ширине/высоте кадра, полям и интервалу. Допускается до 4096 кадров. Можно уточнить прямоугольник выбранного кадра вручную.
- Настройте pivot от 0 до 1, отсчитываемый от верхнего левого угла изображения;
[0.5, 0.5]— центр,[0.5, 1]— низ. Flip X/Y отражают изображение вокруг этой точки. - Сохраните ресурс. Его настройки общие для всех использующих его объектов. Открыть их повторно можно через Нарезка и pivot… в инспекторе или ПКМ по ресурсу.
Двойной клик по изображению в ресурсах или перетаскивание в сцену создаёт спрайт. Инспектор позволяет выбрать кадр, явно задать размер вместо PPU, цвет, непрозрачность, отражение, слой и порядок. Больший слой/порядок рисуется позже. При одинаковом порядке sortY помещает объекты с меньшим Y перед объектами с большим Y. Глубина относительно непрозрачной 3D-геометрии сохраняется. По умолчанию спрайты не зависят от освещения; Освещение 3D включает существующее PBR-освещение сцены.
Добавьте Анимация спрайта. Каждый клип содержит название, номера кадров через запятую, FPS и признак цикла. Автозапуск выбирает начальный клип, Просмотр воспроизводит его в редакторе. Для Character2D опция Авто: idle / run / jump переключает одноимённые клипы по скорости и grounded, а направление движения отражает спрайт по X. Однократный клип удерживает последний кадр. Пауза останавливает время анимации.
Изменение нарезки не может молча сломать используемые кадры: такая транзакция отклоняется. Сначала исправьте ссылки в спрайтах, клипах и Tilemap.
Tilemap
Создайте Карту тайлов, выберите изображение-атлас, размер тайла в единицах сцены и размеры сетки. Карта начинается в локальной точке [0,0], растёт вправо и вверх. Максимум 512×512 ячеек и 65536 заполненных тайлов.
В режиме 2D выберите тайл в палитре и рисуйте ЛКМ. Доступны кисть, ластик и связная заливка. Один мазок — одна транзакция и один шаг Undo. Q/W/E/R завершают рисование и возвращают инструменты выбора/трансформации. ПКМ или средняя кнопка панорамируют вид, колесо меняет масштаб. Опция Шаг 0.5 привязывает перемещение объектов к сетке.
Карта отображается одной сеткой, а соседние твёрдые тайлы объединяются в прямоугольные коллайдеры. Коллизии тайлов создаёт неподвижное тело Rapier2D. В документе отдельному тайлу можно задать solid:false. Динамическая физическая Tilemap не поддерживается.
Физика и камера
| Компонент | Возможности |
|---|---|
collider2d |
Прямоугольник, круг, капсула или выпуклый полигон из 3–64 последовательно заданных точек; локальное смещение, триггер, группы взаимодействия |
rigidbody2d |
Fixed/dynamic/kinematic, масса, трение, упругость, сопротивление, гравитация, CCD, блокировка вращения |
character2d |
Platformer/topDown, встроенный ввод или управление скриптом, скорость, прыжок, гравитация, ступени, grounded и контакты |
joint2d |
Жёсткое соединение, шарнир, верёвка, пружина; два тела и локальные точки крепления |
camera.mode="2d" |
Ортографическая XY-камера, ширина кадра, слежение за объектом, смещение, Pixel Perfect и PPU |
Добавление Character2D через редактор также создаёт требуемые Collider2D и кинематическое тело. Контур выбранного коллайдера отображается в редакторе. membership и mask — 16-битные маски; взаимодействие должно разрешаться с обеих сторон. Изменение enabled из скрипта действует во время игры.
Односторонняя платформа — неподвижный горизонтальный прямоугольник с oneWay:true. Персонаж проходит через неё снизу и приземляется сверху. Для произвольно повёрнутых/движущихся платформ отдельный эффектор пока не реализован.
Для физики XY объект и его родители могут вращаться только вокруг Z; родителям нужен одинаковый масштаб X/Y. Сам спрайт без физики может свободно вращаться в 3D. Не назначайте 2D- и 3D-физику одному объекту. Коллайдеры не вычисляются автоматически по непрозрачным пикселям спрайта.
У камеры bounds:[minX,minY,maxX,maxY] ограничивает положение её центра. Pixel Perfect округляет позицию к пиксельной сетке и выбирает целочисленный масштаб изображения; при маленьком viewport видимая область может быть меньше запрошенной ширины, чтобы не дробить пиксели.
Скрипты и MCP
Скрипты выполняются существующим Worker. Для управления персонажем из скрипта отключите character2d.controls. API:
({
update(api, dt) {
api.velocity({ x: api.input.x * 5 });
if (api.input.jumpPressed && api.physics().grounded)
api.velocity({ y: 8 });
if (api.position()[1] < -20) api.teleport([3, 2, 0]);
},
collision2d(api, event) {
// События приходят до update; started=false означает завершение контакта.
if (event.started && event.sensor) api.log('Триггер: ' + event.otherId);
}
})
api.input.y — вертикальный ввод в XY (тот же WASD/джойстик, что z для 3D). api.move([dx,dy,0]) задаёт смещение; для физического объекта это мировые оси. api.velocity({x?,y?,gravityScale?}) задаёт скорость, api.impulse2D([x,y]) прикладывает импульс к динамическому телу, api.rotate2D(radians) вращает вокруг Z. api.animate(name, loop) запускает клип. api.physics() возвращает dimension:2, скорость, grounded и контакты; grounded/контакты контроллера предназначены для кинематических персонажей.
Префабы, spawn, destroy, смена сцены, сохранение и Undo работают с 2D-компонентами. Внутренние ссылки шарниров переназначаются при копировании/создании экземпляров. Форма и масштаб физического коллайдера строятся при Play; структурные изменения физики из скрипта требуют перезапуска.
MCP asset_import_image импортирует PNG/JPEG/WebP из base64 или пути внутри папки проекта. Настройки asset.image содержат width, height, pixelsPerUnit, filter и frames:[{name,x,y,width,height,pivot}]. Используйте asset.upsert для настройки атласа, scene_create с mode:"2d", scene.configure для существующей сцены и component.set/node.create через транзакции для компонентов. runtime_input принимает x/y, jump; runtime_snapshot включает physics и текущие sprites с кадрами и клипами.
Сохранение и сборки
Изображения, кадры, клипы и Tilemap сохраняются в .forma и IndexedDB вместе с проектом. Web ZIP содержит изображения в assets/ и оба физических движка в runtime; установленный редактор и MCP для запуска не нужны. Используются те же сборки Linux/Windows/Android, что и для 3D. Производительность и управление на целевых устройствах проверяйте отдельно.
Это реализация рабочего 2D-процесса в общей сцене, а не полное повторение всех пакетов Unity. Отдельных 2D skeleton/skin animation, rule tiles/autotiling, normal-map 2D lights, SpriteShape и визуального графа анимаций здесь пока нет.
Техническая основа: Rapier Character Controller, Rapier collision detection.