如何在ARKit中检测到至少一个平面时收到通知?
解决ARKit平面检测通知不触发的问题
嘿,你的代码没触发预期通知的原因很明确——你用错了ARSession的代理方法!
你当前用的session(_:didUpdate:anchors:)方法,只有当已经存在的锚点被更新(比如平面扩大、位置调整)时才会被调用,而不是当新的平面锚点第一次被检测到的时候。这就是为什么你看不到预期的打印和通知触发。
修正方案
要监听新平面的检测,你需要用session(_:didAdd:anchors:)这个代理方法,同时还要确保你只对ARPlaneAnchor类型的锚点做出反应(因为ARSession可能会添加其他类型的锚点)。
这里是修正后的完整代码:
extension MyViewController: ARSCNViewDelegate, ARSessionDelegate { internal func setupAR() { let scene = SCNScene() sceneView.scene = scene let configuration = ARWorldTrackingConfiguration() configuration.planeDetection = [.horizontal] sceneView.session.delegate = self sceneView.session.run(configuration) } // 监听新锚点的添加(这才是检测到新平面时会调用的方法) public func session(_ session: ARSession, didAdd anchors: [ARAnchor]) { // 过滤出所有平面锚点 let planeAnchors = anchors.compactMap { $0 as? ARPlaneAnchor } if !planeAnchors.isEmpty { print("检测到新平面!") planesDetectedState() // 触发你的通知逻辑 } } // 如果你需要监听平面的更新(比如平面扩大),可以保留这个方法 public func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) { let updatedPlaneAnchors = anchors.compactMap { $0 as? ARPlaneAnchor } if !updatedPlaneAnchors.isEmpty { print("已有平面被更新") // 这里可以处理平面更新后的逻辑,如果需要的话 } } }
额外优化建议
如果你不想每次检测到新平面都重复触发planesDetectedState()(比如第一次检测到平面就足够了),可以添加一个状态变量来记录是否已经触发过通知:
private var hasDetectedPlane = false public func session(_ session: ARSession, didAdd anchors: [ARAnchor]) { let planeAnchors = anchors.compactMap { $0 as? ARPlaneAnchor } if !planeAnchors.isEmpty && !hasDetectedPlane { hasDetectedPlane = true print("第一次检测到平面!") planesDetectedState() } }
这样就能确保你的通知逻辑只会在第一次检测到平面时触发一次,避免重复调用。
内容的提问来源于stack exchange,提问作者Cesare
相关产品推荐
相关产品推荐

