iOS 18中RealityView的unproject方法参数设置及代码示例求助
在iOS 18的RealityView中获取点击平面的3D位置
在传统RealityKit的ARView里,我们用raycast(from:allowing:alignment:)获取点击平面的3D位置。在iOS 18的RealityView中,unproject(_:from:to:ontoPlane:)可以实现相同功能,关键是正确设置ontoPlane参数——它需要传入一个Plane结构体,定义平面的原点和法向量。
完整代码示例
import SwiftUI import RealityKit struct ARContentView: View { @State private var arSession = ARSession() var body: some View { RealityView { content, attachments in // 开启平面检测的AR会话配置 let config = ARWorldTrackingConfiguration() config.planeDetection = .horizontal arSession.run(config) content.session = arSession } .gesture(TapGesture() .targetedToAnyEntity() .onEnded { gestureValue in guard let realityView = gestureValue.view as? RealityView else { return } let tapPoint = gestureValue.location // 优先使用AR会话中检测到的真实平面 if let detectedPlane = arSession.currentFrame?.anchors.compactMap({ $0 as? ARPlaneAnchor }).first { // 从ARPlaneAnchor构造Plane结构体 let targetPlane = Plane( origin: SIMD3<Float>(detectedPlane.center.x, detectedPlane.center.y, detectedPlane.center.z), normal: SIMD3<Float>(detectedPlane.transform.columns.2.x, detectedPlane.transform.columns.2.y, detectedPlane.transform.columns.2.z) ) // 执行unproject获取3D位置 if let worldPosition = realityView.unproject( tapPoint, from: .camera, to: .world, ontoPlane: targetPlane ) { print("点击的平面3D位置:\(worldPosition)") // 示例:在该位置添加一个球体标记 let marker = ModelEntity(mesh: .generateSphere(radius: 0.05)) marker.position = worldPosition realityView.scene.addAnchor(marker) } } else { // 未检测到平面时,使用默认水平平面(y=0) let defaultHorizontalPlane = Plane( origin: SIMD3<Float>(0, 0, 0), normal: SIMD3<Float>(0, 1, 0) // 法向量向上,代表水平平面 ) if let defaultPosition = realityView.unproject( tapPoint, from: .camera, to: .world, ontoPlane: defaultHorizontalPlane ) { print("默认平面3D位置:\(defaultPosition)") } } } ) } }
参数说明
ontoPlane的Plane结构体:origin:平面上任意一点,比如检测到的平面锚点中心。normal:平面的法向量,水平平面用法向量(0,1,0),垂直平面可根据实际需求调整。
- 如果要匹配
ARView中.estimatedPlane的行为,优先使用AR会话检测到的ARPlaneAnchor来构造Plane,这样能精准对应真实环境中的平面。
内容的提问来源于stack exchange,提问作者Nathan Mak
相关产品推荐
相关产品推荐

