如何在RealityKit中创建头部跟随锚点并放置固定按钮(仿JigSpace)
实现VisionOS中头部跟随锚点的固定与位置记录功能
以下是匹配JigSpace式头部跟随确认放置逻辑的完整实现方案:
核心功能实现说明
- 创建头部追踪锚点,让目标实体跟随头部水平移动(保持Y轴贴地)
- 给锚点实体绑定交互按钮,支持点击确认位置
- 点击后停止头部跟随,实体固定在当前位置
- 记录并打印实体最终的世界坐标
完整代码实现
import SwiftUI import RealityKit struct ImmersiveView: View { @State private var headAnchor = AnchorEntity(.head) @State private var floorEntity = ModelEntity() @State private var isFollowingHead = true var body: some View { RealityView { content in // 创建蓝色锚点实体(地面放置的盒子) floorEntity = ModelEntity( mesh: .generateBox(size: 0.1), materials: [SimpleMaterial(color: .blue, isMetallic: false)] ) floorEntity.position = [0, 0.05, 0] // 保持在地面上方5cm // 给锚点实体添加交互按钮(绑定到3D实体上) let buttonView = Button("确认位置") { isFollowingHead = false // 获取并打印最终世界位置 let worldPosition = floorEntity.position(relativeTo: nil) print("锚点最终世界位置:X: \(worldPosition.x), Y: \(worldPosition.y), Z: \(worldPosition.z)") } .padding() .background(.white) .cornerRadius(8) let uiComponent = UIHostingComponent(rootView: buttonView) // 将按钮放在锚点实体上方10cm处 uiComponent.position = [0, 0.1, 0] floorEntity.addChild(uiComponent) // 创建地面锚点,确保实体始终贴地 let floorWorldAnchor = AnchorEntity(world: [0, 0, 0]) floorWorldAnchor.addChild(floorEntity) content.add(headAnchor) content.add(floorWorldAnchor) } update: { _ in // 根据状态决定是否跟随头部移动 guard isFollowingHead else { return } let headWorldPos = headAnchor.position(relativeTo: nil) // 仅更新X/Z轴,保持Y轴固定在地面 floorEntity.position.x = headWorldPos.x floorEntity.position.z = headWorldPos.z } } } @main struct FloorFollowerApp: App { @Environment(\.openImmersiveSpace) private var openImmersiveSpace var body: some Scene { WindowGroup { VStack { Button("进入沉浸式视图") { Task { await openImmersiveSpace(id: "ImmersiveSpace") } } .padding() .font(.title) } } ImmersiveSpace(id: "ImmersiveSpace") { ImmersiveView() } } }
关键逻辑解析
头部追踪与跟随控制:
- 用
AnchorEntity(.head)自动获取头部实时世界位置 - 通过
isFollowingHead状态变量切换跟随/固定状态,update闭包里仅在跟随状态下更新实体的X/Z坐标
- 用
3D实体绑定交互按钮:
- 利用
UIHostingComponent将SwiftUI按钮嵌入3D实体,按钮会随实体同步移动 - 调整按钮相对位置,确保在实体上方清晰可见
- 利用
世界位置记录:
- 点击按钮时调用
position(relativeTo: nil)获取实体的世界坐标(nil代表相对于世界空间) - 直接打印坐标,也可根据需求保存到本地或上传至服务端
- 点击按钮时调用
内容的提问来源于stack exchange,提问作者raed
相关产品推荐
相关产品推荐

