Babylon.js предоставляет гибкую архитектуру для построения 3D-сцен с использованием систем и компонентов. Компонент — это логически обособленный блок функциональности, который можно присоединять к объектам сцены (Meshes, Cameras, Lights). Система — это менеджер компонентов, отвечающий за их обновление и взаимодействие. Такой подход позволяет разделять ответственность кода, улучшать читаемость и повторное использование логики.
В Babylon.js компонентная архитектура строится на следующих принципах:
Компоненты в Babylon.js обычно реализуются через классы с определённым интерфейсом:
class RotatorComponent {
constructor(speed = 0.01) {
this.speed = speed;
}
attach(mesh) {
this.mesh = mesh;
}
update(deltaTime) {
if (this.mesh) {
this.mesh.rotation.y += this.speed * deltaTime;
}
}
}
Ключевые моменты при создании компонентов:
attach(mesh) связывает компонент с объектом сцены.update(deltaTime) вызывается системой каждый кадр для
обновления состояния объекта.Система управляет жизненным циклом компонентов, их регистрацией и обновлением. Стандартная практика — создать отдельный класс системы:
class ComponentSystem {
constructor() {
this.components = [];
}
register(component, mesh) {
component.attach(mesh);
this.components.push(component);
}
update(deltaTime) {
this.components.forEach(c => c.update(deltaTime));
}
}
Особенности работы системы:
update(deltaTime) гарантирует
синхронное выполнение всех компонент на каждом кадре.Babylon.js предоставляет метод
scene.onBeforeRenderObservable, который идеально подходит
для интеграции систем:
const system = new ComponentSystem();
scene.onBeforeRenderObservable.add(() => {
const deltaTime = engine.getDeltaTime();
system.update(deltaTime / 1000); // перевод миллисекунд в секунды
});
Такой подход гарантирует, что все компоненты обновляются синхронно с рендерингом, избегая рассинхронизации анимаций и логики.
Движение и управление камерой Компонент может обрабатывать ввод пользователя и перемещать камеру по сцене, не вмешиваясь в физику или рендеринг.
Анимация объектов Простые анимации вращения, масштабирования или перемещения объектов можно реализовать через отдельный компонент, что облегчает их повторное использование.
Физика и столкновения Компонент отвечает за вычисления столкновений и взаимодействие с физическим движком, оставляя основной объект «чистым» от лишней логики.
Для крупных проектов часто создают несколько систем для разных аспектов сцены: графики, физики, управления ИИ. Каждая система может содержать набор компонентов одного типа и управляться независимо:
const movementSystem = new ComponentSystem();
const animationSystem = new ComponentSystem();
scene.onBeforeRenderObservable.add(() => {
const deltaTime = engine.getDeltaTime() / 1000;
movementSystem.update(deltaTime);
animationSystem.update(deltaTime);
});
Это позволяет масштабировать проект без усложнения архитектуры и сохраняет чёткое разделение ответственности между компонентами.
Такой подход к организации логики через системы и компоненты позволяет создавать гибкие, масштабируемые и легко поддерживаемые 3D-приложения в Babylon.js, где каждый элемент сцены управляется автономно, а общая сцена остаётся структурированной и понятной.