ARCore 中文文档 下载 App

锚点的创建、管理与生命周期

什么是锚点

锚点(Anchor)是 ARCore 中把虚拟物体固定到真实世界某个位置的机制。为什么不直接用一个 Pose 存位置?因为 ARCore 的 SLAM 会持续修正设备对自身位置的估计——随着看到更多特征点,它会发现之前算出的位置有误差,然后整体修正整个地图。

如果你只是把虚拟物体放在某个 Pose 上,当 SLAM 修正了设备姿态时,这个虚拟物体就会"漂"。锚点就是为了解决这个问题:

三种锚点创建方式

1. 基于 Trackable 的锚点(推荐)

从 Hit Test 结果创建锚点,锚点会跟随被 Hit Test 命中的 Trackable(通常是平面或特征点):

// hitResult 是 Hit Test 返回的 Pose
val anchor = session.createAnchor(hitResult)
// 把你的虚拟物体绑定到这个 anchor
virtualObject.createAnchor(anchor)

这种方式的锚点稳定性最高——因为它的位置和一个持续被跟踪的 Trackable 绑定在一起。

2. 世界坐标锚点

直接指定一个绝对世界坐标创建锚点:

val pose = Pose.makeTranslation(0f, -0.3f, -2f)  // 相机前方 2 米,下方 30 厘米
val anchor = session.createAnchor(pose)

这种锚点不绑定任何 Trackable,稳定性取决于当前 SLAM 的精度——如果 SLAM 修正了位置,锚点会跟着漂移。适合一次性展示的场景。

3. 相对 Trackable 的锚点

在一个已有的 Trackable(比如检测到的平面)上创建锚点,指定相对于该 Trackable 的偏移:

val plane = session.getAllTrackables<Plane>().first()
val poseOnPlane = plane.centerPose.compose(Pose.makeTranslation(0.1f, 0f, 0.1f))
val anchor = session.createAnchor(poseOnPlane)

锚点稳定性分级

ARCore 的 Anchor 有 TrackingState,反映当前 SLAM 对这个锚点位置的把握程度:

状态含义建议
TRACKING锚点位置稳定可信正常渲染虚拟物体
PAUSED跟踪暂时中断(比如用户走出了平面范围)可以选择隐藏虚拟物体或淡化它
STOPPED锚点已丢失调用 detach() 释放资源,移除虚拟物体

生命周期与内存管理

创建与销毁

锚点创建后不会自动释放。Session 中所有锚点持续存在,除非你主动调用 detach()。这意味着:

// 每次 createAnchor 都会增加一个锚点
// 如果用户多次点屏幕放置物体,锚点数量会持续增长

// 用完后必须释放
anchor.detach()

Session 暂停或销毁时,所有锚点会自动 detach。但在长生命周期 Session 中(比如用户在 AR 环境中玩 20 分钟),及时清理不再需要的锚点是好习惯。

锚点池策略

对于需要频繁创建临时锚点的场景(比如让用户拖动虚拟物体预览位置),建议:

// 方案一:用完即弃
private val activeAnchors = mutableListOf<Anchor>()

fun placeObject(pose: Pose) {
    activeAnchors.forEach { it.detach() }  // 清掉旧的
    activeAnchors.clear()

    val anchor = session.createAnchor(pose)
    activeAnchors.add(anchor)
}

// 方案二:复用同一锚点
private var currentAnchor: Anchor? = null

fun moveObject(newPose: Pose) {
    currentAnchor?.detach()
    currentAnchor = session.createAnchor(newPose)
}

查询所有锚点

// 获取当前 Session 中所有活动锚点
val allAnchors = session.getAllAnchors()

// 筛选出仍然在跟踪的锚点
val activeAnchors = session.getAllAnchors()
    .filter { it.trackingState == TrackingState.TRACKING }

Cloud Anchors(进阶)

普通锚点只在本地设备上有效——换一台设备看不到你放的虚拟物体。Cloud Anchors 解决的就是这个问题,它会把锚点的特征点地图上传到 Google Cloud,其他设备下载地图后就能在同一位置创建同一个锚点。

Cloud Anchors 的 API 使用模式:

// 托管锚点:本地上传
session.hostCloudAnchor(anchor)  // 返回 CloudAnchorHostFuture
// 托管完成后获得一个 anchorId(字符串)

// 解析锚点:其他设备用这个 ID 下载
session.resolveCloudAnchor(anchorId)  // 返回 CloudAnchorResolveFuture
// 解析完成后得到可以和普通锚点一样用的 Anchor

Cloud Anchors 有配额限制,详见定价授权页面。