ARCore 中文文档 下载 App

Instant Placement API 让用户立即放置物体

为什么需要 Instant Placement

传统的 ARCore 流程有一个体验问题:

  1. 用户打开 AR 应用
  2. 应用引导用户"缓慢扫一下周围"
  3. 用户扫了几秒,ARCore 检测出几个平面
  4. 用户再点屏幕放置虚拟物体
  5. 物体才出现

这个流程在早期 AR 应用(比如 IKEA Place 的早期版本)中很常见,用户经常在等待平面检测时就关掉了应用。

Instant Placement(即时放置)API 的目标是:用户点屏幕的瞬间就放一个物体,不用等平面检测。ARCore 会用屏幕点击坐标 + 一个"估计距离"(默认 1 米)来先给出一个近似位置,然后在后续跟踪中不断修正,最终当精确位置确定后,虚拟物体的位置会自动对齐到真实表面上。

工作原理

Instant Placement 的返回值经历两个阶段:

阶段TrackingMethod精度含义
初始估计SCREENSPACE_WITH_APPROXIMATE_DISTANCE低基于屏幕点击 + 用户传入的 approximateDistanceMeters 计算的近似位置
精确跟踪FULL_TRACKING高ARCore 检测到了该区域的特征点/平面后,自动更新为精确位置

关键是这两个阶段的切换对开发者是透明的——你只需要在初始帧创建一个 Anchor,后续 ARCore 会自动更新这个 Anchor 的 Pose,你的虚拟物体渲染位置会自然跟着修正。

Android API 使用

步骤一:检查设备支持

Instant Placement 是较新的 API,需要确认设备支持:

// 检查设备是否支持 Instant Placement
val instantPlacementSupported = session.isInstantPlacementModeSupported()

步骤二:配置 Session

session.configure(
    Session.Config(context).apply {
        setInstantPlacementMode(Session.Config.InstantPlacementMode.LOCAL_Y_UP)
    }
)

两种模式:

步骤三:Instant Placement Hit Test

// 用户点击屏幕时
val approximateDistanceMeters = 1.0f  // 假设虚拟物体在 1 米外
val hitResults = frame.hitTestInstantPlacement(tapX, tapY, approximateDistanceMeters)

// 解析结果
val firstHit = hitResults.firstOrNull() ?: return

// InstantPlacementPoint 是 HitResult 的具体类型
val point = firstHit as InstantPlacementPoint

// 创建锚点
val anchor = session.createAnchor(point.pose)

// 此时 point.trackingMethod 是 SCREENSPACE_WITH_APPROXIMATE_DISTANCE
// 后续帧会变成 FULL_TRACKING,锚点 Pose 也会自动修正

步骤四:监听 TrackingMethod 变化(可选)

如果你想在物体位置从"近似"变为"精确"时给用户一个视觉反馈:

// 在每帧更新后检查
if (point.trackingMethodChangedSinceLastFrame) {
    when (point.trackingMethod) {
        InstantPlacementPoint.TrackingMethod.SCREENSPACE_WITH_APPROXIMATE_DISTANCE -> {
            // 物体处于近似位置,可以显示半透明或阴影效果提示"还在对齐中"
        }
        InstantPlacementPoint.TrackingMethod.FULL_TRACKING -> {
            // 物体已对齐到精确位置,可以切换到正常渲染
            fadeOutPlacementGuide()
        }
    }
}

Unity AR Foundation 中使用 Instant Placement

using UnityEngine.XR.ARFoundation;

public class InstantPlacementExample : MonoBehaviour
{
    public ARRaycastManager raycastManager;
    public GameObject virtualPrefab;

    void Update()
    {
        if (Input.touchCount < 1) return;
        var touch = Input.GetTouch(0);
        if (touch.phase != TouchPhase.Began) return;

        // 使用 Instant Placement Raycast(Unity 2021+)
        var hit = raycastManager.RaycastInstantPlacement(
            touch.position,
            approximateDistanceFallback: 1f,
            hit: out ARRaycastHit hitResult
        );

        if (hit)
        {
            // hitResult.pose 初始可能是近似位置
            // AR Foundation 会自动处理后续的跟踪修正
            var placed = Instantiate(virtualPrefab, hitResult.pose.position, hitResult.pose.rotation);

            // 注意:Instant Placement 创建的锚点不是立即稳定的
            // 你可以监听 ARSession 的跟踪状态变化
        }
    }
}

用户体验设计建议

Instant Placement 能让应用"秒响应",但物体位置会在几帧内跳变——给用户的视觉提示很重要:

  1. 初始状态用半透明渲染:让用户知道"物体位置还在对齐中"
  2. 对齐完成后淡化提示:比如位置固定时播放一个微小的缩放动画(从半透明 → 正常)
  3. 鼓励用户移动设备:"慢慢移动一下手机让物体更精确"——ARCore 在用户移动时能更快积累特征点完成对齐
  4. approximateDistanceMeters 参数:根据你的应用场景合理设置——比如家具预览可以设置 1.5-2.0 米,桌面小游戏设置 0.5-1.0 米

与传统 Hit Test 的关系

对比项传统 Hit TestInstant Placement
必须检测到 Plane/Point 才能用是否,随时可用
初始位置精度高低(近似距离)
后续是否自动修正否,位置固定是,跟踪变好后自动对齐
对用户的引导需求需"先扫一下房间"直接点就行
适用场景精确放置家具即时放置 + 后期调整

实际应用中两者经常组合使用:Instant Placement 让用户秒放,ARCore 在后台同时尝试做传统 Hit Test,成功后 Anchor 自动切换到精确位置。