Работа с системами через sceneEl.systems

В A-Frame системы (systems) представляют собой централизованные менеджеры логики для компонентов и сущностей. Они позволяют инкапсулировать общую функциональность, которая может использоваться несколькими компонентами или даже всей сценой. Доступ к системам осуществляется через объект сцены sceneEl.systems, что открывает прямой путь к методам и данным систем из любого места в коде.


Структура sceneEl.systems

sceneEl.systems — это объект, ключи которого соответствуют именам зарегистрированных систем, а значения — экземпляры этих систем. Каждая система, созданная через AFRAME.registerSystem(name, definition), автоматически добавляется в sceneEl.systems после инициализации сцены.

Пример структуры объекта:

{
  physics: PhysicsSystem { ... },
  sound: SoundSystem { ... },
  network: NetworkSystem { ... }
}

Через этот объект можно напрямую вызывать методы системы или читать её состояние.


Регистрация и инициализация системы

Регистрация системы происходит с помощью функции AFRAME.registerSystem(name, definition):

AFRAME.registerSystem('score', {
  schema: {
    initial: { type: 'int', default: 0 }
  },

  init: function () {
    this.points = this.data.initial;
  },

  addPoints: function (value) {
    this.points += value;
  },

  getPoints: function () {
    return this.points;
  }
});

После регистрации система автоматически инициализируется при загрузке сцены. Объект sceneEl.systems.score будет содержать экземпляр системы с доступом ко всем методам (addPoints, getPoints) и свойствам (points).


Доступ к системе из компонентов

Компоненты могут напрямую взаимодействовать с системами через this.el.sceneEl.systems:

AFRAME.registerComponent('score-display', {
  tick: function () {
    const scoreSystem = this.el.sceneEl.systems.score;
    console.log('Текущий счёт:', scoreSystem.getPoints());
  }
});

Ключевые моменты:

  • Доступ только после инициализации сцены. До завершения init сцены системы могут быть ещё не созданы.
  • Безопасность типов. Проверка существования системы перед использованием предотвращает ошибки:
const physicsSystem = this.el.sceneEl.systems.physics;
if (physicsSystem) {
  physicsSystem.step();
}

Взаимодействие нескольких компонентов с одной системой

Системы обеспечивают централизованное хранение состояния. Несколько компонентов могут использовать одну систему для синхронизации действий:

AFRAME.registerComponent('enemy', {
  init: function () {
    const scoreSystem = this.el.sceneEl.systems.score;
    this.el.addEventListener('defeated', () => {
      scoreSystem.addPoints(10);
    });
  }
});

AFRAME.registerComponent('treasure', {
  init: function () {
    const scoreSystem = this.el.sceneEl.systems.score;
    this.el.addEventListener('collected', () => {
      scoreSystem.addPoints(50);
    });
  }
});

Здесь score используется как единый источник правды для всех событий, влияющих на счёт.


Динамическое создание и удаление систем

Хотя чаще системы регистрируются статически, A-Frame позволяет добавлять их динамически, например, для модульных сцен. После регистрации можно обратиться к системе так же, как к любой статической:

const mySystem = sceneEl.systems.myDynamicSystem;
mySystem.doSomething();

Удаление системы вручную не предусмотрено напрямую, но можно очистить её состояние или отключить её методы для управления жизненным циклом.


Лучшие практики работы с sceneEl.systems

  • Инкапсуляция логики: Системы должны содержать логику, общую для нескольких компонентов, а не служить контейнером для всего.
  • Инициализация через init и schema: Использование schema обеспечивает автоматическую обработку параметров конфигурации.
  • Безопасный доступ: Всегда проверять существование системы перед вызовом методов, особенно в динамически изменяемых сценах.
  • Единый источник состояния: Избегать дублирования состояния в компонентах, использовать систему для синхронизации.

Взаимодействие систем между собой

Системы могут взаимодействовать напрямую, используя sceneEl.systems:

AFRAME.registerSystem('level', {
  init: function () {
    this.el.addEventListener('next-level', () => {
      const scoreSystem = this.el.systems.score;
      if (scoreSystem.getPoints() > 100) {
        console.log('Переход на следующий уровень');
      }
    });
  }
});

Это позволяет строить сложные сценарии, где различные системы координируют события сцены.


Вывод

Использование sceneEl.systems предоставляет гибкий способ централизованного управления состоянием и логикой в A-Frame. Оно обеспечивает безопасный и удобный доступ к методам систем, позволяет синхронизировать действия компонентов и строить масштабируемые архитектуры VR-приложений. Понимание этого механизма является ключевым для построения сложных интерактивных сцен.