Лучевой ввод в A-Frame позволяет взаимодействовать с объектами
виртуальной сцены с помощью направленных лучей, исходящих из
контроллеров VR, указателей мыши или других устройств. Он используется
для выбора, активации и манипуляции объектами на расстоянии, заменяя
традиционный физический контакт. В основе лежит компонент
raycaster, который генерирует лучи и отслеживает
пересечения с объектами сцены.
raycasterraycaster является ключевым инструментом для реализации
лучевого ввода. Основные свойства компонента:
objects — CSS-селектор или список
объектов, с которыми луч будет взаимодействовать
(.clickable, #target).far / near — максимальная
и минимальная длина луча в единицах сцены (по умолчанию
far: 1000, near: 0.1).showLine — если true,
визуально отображает луч в виде линии.direction — вектор направления луча,
обычно 0 0 -1 для контроллера, направленного вперед.Пример подключения к контроллеру:
<a-entity id="right-hand" laser-controls="hand: right">
<a-entity raycaster="objects: .interactable; showLine: true"></a-entity>
</a-entity>
В этом примере луч создаётся от правого контроллера и взаимодействует
со всеми объектами с классом interactable.
Лучевой ввод в A-Frame генерирует несколько событий, которые можно использовать для реакции на пересечения объектов:
raycaster-intersected — срабатывает,
когда луч впервые пересёк объект.raycaster-intersected-cleared —
срабатывает, когда объект больше не пересекается лучом.click / mouseenter /
mouseleave — работают в сочетании с
cursor для имитации взаимодействия.Пример добавления обработчиков событий на объект:
<a-box class="interactable" position="0 1.5 -3" color="#4CC3D9">
</a-box>
<script>
const box = document.querySelector('.interactable');
box.addEventListener('raycaster-intersected', () => {
box.setAttribute('color', '#EF2D5E');
});
box.addEventListener('raycaster-intersected-cleared', () => {
box.setAttribute('color', '#4CC3D9');
});
</script>
A-Frame поддерживает стандартные контроллеры через компонент
laser-controls или hand-controls. Луч
создаётся автоматически, но можно кастомизировать его свойства. Основные
параметры:
hand — определяет руку
(left или right).model — если true,
отображается 3D-модель контроллера.rayOrigin — точка старта луча
(tip или controller).Пример кастомного луча от контроллера:
<a-entity laser-controls="hand: left" raycaster="objects: .clickable; showLine: true">
</a-entity>
cursorДля взаимодействия с объектами можно использовать компонент
cursor на луче. Это позволяет имитировать клики и
наведение. Основные свойства:
fuse — если true,
запускается таймер активации при наведении.fuseTimeout — продолжительность
таймера в миллисекундах.Пример:
<a-entity laser-controls="hand: right" raycaster="objects: .clickable">
<a-entity cursor="fuse: true; fuseTimeout: 1500"></a-entity>
</a-entity>
raycaster в JavaScriptДля динамических сцен часто нужно обрабатывать пересечения программно. A-Frame предоставляет API:
const raycasterEl = document.querySelector('[raycaster]');
const intersects = raycasterEl.components.raycaster.intersections;
intersects.forEach(intersect => {
console.log('Пересечение с объектом:', intersect.object.el.id);
});
Метод intersections возвращает массив объектов
пересечения с информацией о точке пересечения, нормали поверхности и
расстоянии.
Для сложных сцен с множеством объектов рекомендуется использовать селекторы или фильтры для луча:
.clickable,
.interactive.data-raycastable="true".raycaster можно
исключать определённые объекты, чтобы улучшить производительность.Пример:
<a-entity raycaster="objects: [data-raycastable='true']; far: 10"></a-entity>
Встроенный метод showLine: true создаёт линию от
источника луча до объекта пересечения. Для кастомизации можно
использовать компонент line:
<a-entity id="ray" line="start: 0 0 0; end: 0 0 -1; color: red"></a-entity>
Программно можно обновлять конец линии в зависимости от пересечения:
rayEl.setAttribute('line', 'end', `${intersectPoint.x} ${intersectPoint.y} ${intersectPoint.z}`);
Поддержка двух рук реализуется через два отдельных сущности:
<a-entity laser-controls="hand: left" raycaster="objects: .interactable"></a-entity>
<a-entity laser-controls="hand: right" raycaster="objects: .interactable"></a-entity>
Каждый луч может иметь свои события, визуальные эффекты и фильтры, позволяя пользователю взаимодействовать двумя руками одновременно.
Лучевой ввод широко используется для:
В сочетании с другими компонентами A-Frame, такими как
animation, interaction, state,
лучевой ввод создаёт гибкую и мощную систему взаимодействия без
необходимости физического контакта.