Розроблення механік взаємодії з дополненою реальністю (AR Foundation)
AR Foundation – це абстракція поверх ARKit (iOS) та ARCore (Android), яка дозволяє писати один код під обидві платформи. Але абстракція неповна: під нею живе різна фізика, різна якість плоскостного трекінгу, різна швидкість оновлення depth map. Це означає, що механіки взаємодії потрібно проектувати з врахуванням обох платформ та тестувати на реальних пристроях – не у редакторі.
Placement: розміщення об'єктів у реальному просторі
Базова механіка будь-якого AR-приложення – розмістити віртуальний об'єкт на реальній поверхні. AR Foundation робить це через Raycast проти AR Planes: ARRaycastManager.Raycast() бросає промінь із точки дотику екрану, повертає список ARRaycastHit з позицією та нормаллю площини.
Стандартна помилка: викликати Raycast кожний кадр в Update без debounce. Це працює, але на складних сценах ARCore витрачає 2–4 мс на raycast – це з'їдає бюджет. Правильно: raycast тільки при зміні позиції пальця, з мінімальним threshold руху 5–10 пікселів.
Інша проблема – площина ще не виявлена. ARCore та ARKit детектують горизонтальні площини за 2–5 секунд на добре текстурованій поверхні. На монотонному білому столі – ніколи. Потрібен feedback UI: візуальний індикатор пошуку площин, інструкція "рухайте камеру над поверхнею".
ARAnchor: чому Transform.position недостатньо
Якщо розмістити об'єкт в AR та просто запам'ятати його worldPosition – при переміщенні з пристроєм об'єкт "пливе" щодо реального світу. ARKit та ARCore періодично перераховують світові координати при поліпшенні трекінгу. Об'єкт без якоря дрейфує.
ARAnchor – це точка, яку AR система зобов'язується стежити та коригувати автоматично. Об'єкт має бути child ARAnchor'а, не просто помішений у світові координати.
В AR Foundation: ARAnchorManager.TryAddAnchorAsync(pose) повертає ARAnchor, до якого креплять контент. При переоткритті сцени (Persistent AR) – ARCore Cloud Anchors або ARKit WorldMap для збереження якорів між сеансами.
Occlusion: реальний світ закриває віртуальний об'єкт
Без occlusion віртуальний об'єкт рендерится поверх всього: ваза на столі відображається крізь вашу руку. Це негайно руйнує ілюзію.
AROcclusionManager в AR Foundation надає depth texture від сенсора (LiDAR на iPhone Pro, алгоритмічна оцінка глибини через камеру на Android). URP шейдер повинен перевіряти depth texture перед записом фрагмента – це Environment Depth Occlusion.
Налаштування: AROcclusionManager.environmentDepthMode = EnvironmentDepthMode.Best (максимальна якість), occlusionPreferenceMode = OcclusionPreferenceMode.PreferEnvironmentOcclusion. На Android без LiDAR глибина оціночна – occlusion працює грубо, з артефактами на краях. На iPhone Pro з LiDAR – точно.
Стандартний URP Lit без кастомного шейдера не використовує AR depth texture. Потрібен або ShaderGraph з AROcclusion ноддю з AR Foundation Shader Framework, або кастомний HLSL з ручним depth comparison.
Interaction: тап, drag, масштаб
В AR немає фізичних контролерів – взаємодія через тачскрин. Для об'єктів в AR стандартний набір:
Tap to select: ARRaycastManager + Physics.Raycast проти collider об'єкта. При попаданні – виділення через зміну матеріалу або outline.
Drag (translate): при переміщенні пальця – новий AR Raycast повертає нову позицію площини, об'єкт Lerp-ится до неї. Без Lerp об'єкт прыгає. speed = 15f в MoveTowards дає плавне слідування без залипання.
Pinch to scale: Touch[0] та Touch[1] – два пальці. Поточна дистанція між ними vs. попередня = scale delta. transform.localScale *= scaleDelta з затиском у Vector3.one * minScale та maxScale.
Rotation: один палець, drag по горизонталі = rotation вокруг world-up axis. Два пальці, twist = rotation. Для AR рекомендується обмежувати rotation тільки вокруг Y-axis – обертання по X або Z ломає ощущення "об'єкт стоїть на поверхні".
Терміни: базове placement + interaction (tap/drag/scale) – 3–5 робочих днів; full AR experience з Anchors, Occlusion, Persistent Cloud Anchors – 2–4 тижні. Вартість розраховується індивідуально після аналізу вимог.





