Компонент wasd-controls

wasd-controls — встроенный компонент системы управления камерой и объектами сцены, обеспечивающий перемещение с клавиатуры по схеме WASD. Компонент реализует базовую навигацию от первого лица и используется по умолчанию в стандартной камере a-camera. Основан на механизме изменения позиции сущности (entity) в трёхмерном пространстве с учётом направления взгляда.


Архитектура и назначение

Компонент отвечает за:

  • Обработку событий клавиатуры (keydown, keyup)
  • Расчёт вектора движения
  • Изменение позиции объекта на основе delta time
  • Интеграцию с компонентами look-controls и camera

Перемещение осуществляется в локальной системе координат объекта. Это означает, что направление движения вперёд определяется текущим поворотом камеры.

Типовой сценарий использования — управление камерой пользователя в WebXR- или desktop-сцене.


Подключение и базовое использование

По умолчанию wasd-controls автоматически добавляется к a-camera, если явно не отключён:

<a-camera></a-camera>

Эквивалентная явная запись:

<a-camera wasd-controls></a-camera>

Отключение:

<a-camera wasd-controls="enabled: false"></a-camera>

Добавление к произвольной сущности:

<a-entity wasd-controls position="0 1.6 0"></a-entity>

Принцип работы

Компонент:

  1. Отслеживает нажатия клавиш:

    • W — движение вперёд
    • S — назад
    • A — влево
    • D — вправо
    • стрелки клавиатуры (в зависимости от конфигурации)
  2. Создаёт вектор направления движения.

  3. Нормализует его.

  4. Умножает на скорость (acceleration).

  5. Умножает на delta time для независимости от FPS.

  6. Применяет к позиции объекта.

Обновление происходит в методе tick(), который вызывается каждый кадр.


Свойства компонента

wasd-controls поддерживает набор параметров конфигурации.

acceleration

Скорость движения в единицах сцены в секунду.

<a-camera wasd-controls="acceleration: 50"></a-camera>

Чем больше значение — тем быстрее перемещение.


adEnabled

Включает или отключает боковое движение (A/D).

wasd-controls="adEnabled: false"

wsEnabled

Управление движением вперёд/назад (W/S).

wasd-controls="wsEnabled: false"

fly

Разрешает движение по вертикальной оси.

По умолчанию перемещение ограничено плоскостью XZ. При включении fly становится доступно движение по Y.

wasd-controls="fly: true"

constrainToNavMesh (при использовании nav-mesh)

Позволяет ограничить перемещение навигационной сеткой. Используется в сценах с системой навигации.


enabled

Полностью включает или отключает компонент.

wasd-controls="enabled: false"

Взаимодействие с look-controls

Наиболее часто wasd-controls используется совместно с look-controls:

<a-camera look-controls wasd-controls></a-camera>
  • look-controls отвечает за поворот камеры мышью или гироскопом.
  • wasd-controls отвечает за перемещение.

Вектор движения вперёд вычисляется с учётом текущего поворота камеры, поэтому направление всегда соответствует взгляду пользователя.


Ограничение движения по высоте

Стандартная реализация не учитывает гравитацию и коллизии. Перемещение по Y возможно только при fly: true.

Для симуляции ходьбы по земле применяются:

  • ограничение Y вручную
  • физические движки (например, aframe-physics-system)
  • использование навигационной сетки

Пример ограничения высоты через компонент:

AFRAME.registerComponent('lock-height', {
  tick: function () {
    this.el.object3D.position.y = 1.6;
  }
});

Изменение скорости во время выполнения

Скорость можно динамически изменять:

const camera = document.querySelector('a-camera');
camera.setAttribute('wasd-controls', 'acceleration', 100);

Это позволяет реализовать:

  • режим бега
  • замедление
  • ускорение при взаимодействии

Кастомизация клавиш

Стандартная реализация использует фиксированные клавиши. Для глубокой кастомизации требуется:

  • создать собственный компонент
  • переопределить обработчики клавиатуры
  • либо модифицировать исходный код компонента

Пример расширения:

AFRAME.registerComponent('custom-wasd', {
  init: function () {
    this.keys = {};

    window.addEventListener('keydown', e => {
      this.keys[e.code] = true;
    });

    window.addEventListener('keyup', e => {
      this.keys[e.code] = false;
    });
  },

  tick: function (time, delta) {
    const velocity = delta / 1000 * 5;

    if (this.keys['KeyW']) {
      this.el.object3D.position.z -= velocity;
    }
  }
});

Влияние FPS и delta time

wasd-controls использует delta, передаваемый в tick(time, delta). Это обеспечивает:

  • одинаковую скорость на разных устройствах
  • независимость от частоты кадров
  • плавность движения

Формула перемещения:

смещение = скорость × (delta / 1000)

Работа в VR-режиме

В режиме VR:

  • управление WASD обычно отключается
  • приоритет получают контроллеры или телепортация
  • можно принудительно оставить WASD активным
<a-camera wasd-controls="enabled: true"></a-camera>

Однако в VR это применяется преимущественно для отладки.


Коллизии и ограничения

Компонент не реализует:

  • проверку столкновений
  • физику
  • ограничение границ сцены

Для добавления коллизий используются:

  • физические системы
  • кастомные проверки пересечения
  • навигационные меши

Пример простой проверки границ:

AFRAME.registerComponent('bounds', {
  tick: function () {
    const pos = this.el.object3D.position;

    pos.x = Math.max(-10, Math.min(10, pos.x));
    pos.z = Math.max(-10, Math.min(10, pos.z));
  }
});

Оптимизация

При большом количестве логики в tick рекомендуется:

  • минимизировать вычисления
  • избегать создания новых объектов в каждом кадре
  • использовать повторно векторы THREE.Vector3
  • отключать компонент при ненужности

Типовые сценарии применения

  1. Навигация в виртуальных турах
  2. Архитектурные визуализации
  3. Прототипирование 3D-интерфейсов
  4. Игровые сцены
  5. Обучающие симуляции

Внутреннее устройство

Внутри компонента:

  • хранится объект состояния клавиш
  • создаётся вектор направления
  • используется object3D.getWorldDirection
  • применяется трансформация с учётом поворота

Система основана на объектной модели three.js, через object3D каждой сущности.


Отключение при потере фокуса

Стандартное поведение:

  • при потере фокуса окна движение прекращается
  • обработчики клавиш корректно очищают состояние

Это предотвращает «залипание» движения.


Совместимость

Компонент работает:

  • в desktop-браузерах
  • в мобильных браузерах (при наличии клавиатуры)
  • в режиме immersive VR (ограниченно)

Поддерживается всеми современными браузерами с WebGL.


wasd-controls остаётся базовым инструментом навигации в сценах A-Frame. Его простота делает его удобным для быстрого прототипирования, а расширяемость позволяет адаптировать под игровые и симуляционные задачи любой сложности.