Настройка распознавания жестов рук для управления в AR играх
Управление жестами в AR — это когда игра отвечает на форму руки, а не на нажатие кнопки. Открытая ладонь вызывает меню. Щипок выбирает объект. Сжатый кулак — атака. Звучит как магия, реализуется как математика над joint positions.
Что даёт платформа и что нужно строить самостоятельно
Meta Quest (через Meta Hand Tracking SDK или OpenXR Hand Interaction Extension) предоставляет 26 joint positions пальцев и запястья в мировых координатах, обновляемых с частотой 30–60 Hz. Это сырые данные — позиции костей.
ARKit (iOS, через AR Foundation) с Vision framework даёт аналогичный набор hand landmarks через ARHandTrackingConfiguration, доступный с iOS 18. На Android через ARCore прямого Hand Tracking API нет — используются сторонние решения (MediaPipe через ML Kit) или Google ARCore Geospatial + кастомная ML модель.
Из коробки вы получаете данные, но не жесты. Распознавание жестов — ваша задача.
Как строится gesture recognizer
Каждый жест — это набор условий над joint positions:
Pinch (щипок): расстояние между ThumbTip и IndexTip < threshold (обычно 2–3 см в мировых единицах). Плюс дополнительная проверка: MiddleTip, RingTip, PinkyTip далеко от большого пальца (открыты). Без второго условия кулак ложно срабатывает как pinch.
Open Palm: все fingertip joints на значительном расстоянии от Palm joint. Проверяем Vector3.Distance(fingertip, palm) > openThreshold для всех пяти пальцев. Дополнительно — нормаль ладони (вектор от Palm к Middle Metacarpal) должна смотреть примерно в сторону камеры, иначе открытая ладонь сзади тоже сработает.
Point (указательный жест): IndexTip вытянут (большое расстояние от IndexMetacarpal), остальные пальцы согнуты (малое расстояние tip→metacarpal). Плюс угол между вектором IndexProximal → IndexTip и вектором ладони.
Это не магия — это несколько distance checks и dot products в Update().
Debounce и предотвращение ложных срабатываний
Жесты нужно debounce. Рука естественно дрожит — ThumbTip и IndexTip могут случайно сближаться и расходиться быстрее, чем 1 кадр. Без debounce pinch срабатывает 5 раз в секунду при попытке сделать его один раз.
Стандартная техника: state machine с временным порогом. Жест считается активным, только если условие выполнялось непрерывно минимум N кадров (или T секунд). Значения: 3–5 кадров для быстрых жестов, 10–15 кадров (≈ 0.2 с при 60 Hz) для статических поз типа Open Palm.
Дополнительно — confidence фильтр. Meta Hand Tracking SDK предоставляет OVRHand.HandConfidence — при низкой достоверности трекинга (рука частично вне поля зрения, плохое освещение) жесты не обрабатываются. Это критично для AR на смартфоне, где условия съёмки непредсказуемы.
Интеграция в AR Foundation
В AR Foundation (Unity) Hand Tracking подключается через XRHandSubsystem (пакет com.unity.xr.hands). XRHandJoint для каждого joint даёт TryGetPose() — позицию и ротацию в пространстве. Gesture recognizer подписывается на XRHandSubsystem.handsUpdated event и обрабатывает данные в колбэке.
Важно не делать heavy computation в этом колбэке — он может вызываться не в main thread. Либо буферизовать данные и обрабатывать в Update, либо использовать Job System с IJobParallelFor для многорукого распознавания.
Для MediaPipe на Android — отдельная интеграция через Native Plugin или готовые обёртки (mediapipe-unity-plugin), данные приходят через callback с ML-результатами.
Сроки: базовые 3–5 жестов на Meta SDK — 3–5 рабочих дней; полная система с debounce, confidence filter и 10+ жестами для AR Foundation — 1–2 недели. Стоимость определяется индивидуально.





