You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:00:05