Пикинг спрайтов

Пикинг (picking) спрайтов в Babylon.js представляет собой процесс определения, какой спрайт пользователь выбрал с помощью указателя мыши или касания. В отличие от 3D-мешей, спрайты являются плоскими изображениями, отрисовываемыми на сцене с помощью SpriteManager. Они обладают упрощённой геометрией, что делает их легкими для рендеринга, но требует особого подхода при взаимодействии с ними.


Создание и настройка спрайтов

Для работы со спрайтами сначала создается SpriteManager. Он управляет группой спрайтов и обеспечивает их рендеринг:

const spriteManager = new BABYLON.SpriteManager(
    "spriteManager",      // имя менеджера
    "textures/character.png", // путь к текстуре
    100,                  // максимальное количество спрайтов
    { width: 64, height: 64 }, // размеры каждого спрайта
    scene                  // сцена
);

Каждый спрайт создается через Sprite:

const sprite = new BABYLON.Sprite("hero", spriteManager);
sprite.position = new BABYLON.Vector3(0, 1, 0);
sprite.size = 2;

Ключевой момент: позиция спрайта определяется в 3D-пространстве, несмотря на то, что визуально он всегда ориентирован к камере (billboard).


Механизм пикинга

Babylon.js поддерживает три типа пикинга для спрайтов:

  1. Sprite Picking (точечный): определяет, пересек ли указатель спрайт. Использует ограничивающие прямоугольники (bounding box) спрайтов.
  2. Ray Picking (лучевой): строится луч от камеры через курсор в сцену. Используется для более точного взаимодействия с 3D-объектами и спрайтами.
  3. Multi-Picking: позволяет обнаруживать несколько пересечений за один клик.

Использование scene.pickSprite

Метод scene.pickSprite позволяет определить, какой спрайт был выбран:

const pointerX = scene.pointerX;
const pointerY = scene.pointerY;

const pickedSprite = scene.pickSprite(pointerX, pointerY, (sprite) => {
    // Фильтр: учитываем только видимые спрайты
    return sprite.isVisible;
}, false);

Параметры метода:

  • pointerX, pointerY: координаты указателя на экране.
  • predicate: функция-фильтр для исключения спрайтов.
  • fastCheck: если true, проверка выполняется быстро, но с меньшей точностью.

Результат — объект PickingInfo, содержащий:

  • hit — boolean, есть ли попадание.
  • pickedSprite — ссылка на выбранный спрайт.
  • distance — расстояние от камеры до спрайта.

Ray Picking для спрайтов

Хотя спрайты являются двухмерными, Babylon.js позволяет использовать луч для взаимодействия с ними. Для этого строится луч через курсор:

const ray = scene.createPickingRay(scene.pointerX, scene.pointerY, BABYLON.Matrix.Identity(), camera);
const pickedSprite = scene.pickWithRay(ray, (sprite) => sprite.isVisible);

Преимущество: можно использовать совместно с другими объектами сцены, например, мешами, и получать однотипные результаты для всех типов объектов.


События взаимодействия

Для упрощенного реагирования на клики можно использовать обработчики событий на уровне сцены:

scene.onPointerObservable.add((pointerInfo) => {
    switch (pointerInfo.type) {
        case BABYLON.PointerEventTypes.POINTERDOWN:
            const sprite = scene.pickSprite(pointerInfo.event.clientX, pointerInfo.event.clientY);
            if (sprite.hit) {
                sprite.pickedSprite.playAnimation(0, 5, true, 100);
            }
            break;
    }
});

Особенности:

  • Спрайты всегда ориентированы к камере, поэтому для точного попадания важно учитывать их size и position.
  • Обработка анимаций спрайтов (например, playAnimation) часто привязана к событиям пикинга.

Фильтры и слои

Для более сложной логики часто применяют фильтры и слои:

  • Predicate-функции: позволяют исключить невидимые или заблокированные спрайты.
  • Слои (layerMask): дают возможность ограничивать пикинг только определенными группами объектов.
sprite.layerMask = 0x10000000;
const picked = scene.pickSprite(pointerX, pointerY, (s) => (s.layerMask & 0x10000000) !== 0);

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


Оптимизация

  1. Fast Check: если не требуется высокая точность, выставление fastCheck: true ускоряет обработку.
  2. Максимальное количество спрайтов: разумное ограничение количества спрайтов в менеджере уменьшает нагрузку.
  3. Bounding Box: визуально крупные спрайты с маленькой текстурой могут иметь меньший width/height для пикинга, чтобы улучшить точность попадания.

Заключение по технической реализации

Пикинг спрайтов в Babylon.js сочетает простоту управления плоскими изображениями и мощь стандартных 3D-пикеров. Методы pickSprite и pickWithRay обеспечивают гибкость для игр и визуальных приложений, а фильтры и слои позволяют создавать сложные интерактивные сцены. Правильная настройка размеров спрайтов, ориентации и фильтров гарантирует точное и отзывчивое взаимодействие пользователя со сценой.