ARKit 平面检测 - “ARView”类型的值没有成员“会话”

Posted

技术标签:

【中文标题】ARKit 平面检测 - “ARView”类型的值没有成员“会话”【英文标题】:ARKit Plane Detection - Value of type 'ARView' has no member 'session' 【发布时间】:2019-11-20 05:17:09 【问题描述】:

我正在尝试将平面检测添加到一个简单的 ARKit 应用程序中。我想在垂直平面上放一张图片。

所以首先我需要检测平面,然后我可以添加我在 RealityKit 中创建的对象锚。

但问题是我不确定使用 ARKit 3 和 Xcode 11 检测飞机并将其添加到我的场景中的正确方法。

应该很简单:

import ARKit
import RealityKit

@IBOutlet var arView: ARView!

override func viewDidLoad() 
    super.viewDidLoad()

    let arConfiguration = ARWorldTrackingConfiguration()
    arConfiguration.planeDetection = .horizontal
    arView.session.run(arConfiguration)
 

但我收到以下错误:

“ARView”类型的值没有成员“会话”

我什至尝试了以下苹果在他们的 WWDC 演示 (4:27) 中用作示例的方法,

Apple Demo!

let anchor = AnchorEntity(plane: .verticle, minimumBounds: [0.2, 0.2])
arView.scene.addAnchor(anchor)

但在尝试创建 AnchorEntity 时出现以下错误

表达式类型“AnchorEntity”在没有更多上下文的情况下是模棱两可的

import UIKit
import RealityKit
import ARKit

class ViewController: UIViewController 

    @IBOutlet var arView: ARView!

    override func viewWillAppear(_ animated: Bool) 
        super.viewWillAppear(animated)

        // Create a session configuration
    

    override func viewDidLoad() 
        super.viewDidLoad()
    

    func addFrame() 
        // Load the "Box" scene from the "Experience" Reality File
        let boxAnchor = try! Experience.loadBox()

        // Add the box anchor to the scene
        arView.scene.anchors.append(boxAnchor)
    

【问题讨论】:

在 Xcode 13.2 中不再存在这样的问题。 【参考方案1】:

如果您的构建目标设置为模拟器,您会收到此错误。您需要选择实际设备或通用 ios 设备。

我已经为此苦恼了好几次,现在添加以下评论

    // If the following line fails to compile "Value of type 'ARView' has no member 'session'"
    // You need to select a Real Device or Generic iOS Device and not a simulator
    arView.session.run(configuration)

【讨论】:

如果我选择了真实设备,但仍然出现错误怎么办? 您是如何创建 RealityKit ARView 的,使用代码还是使用故事板? 代码。我从 Xcode 12.3 移回 12.2 后出现错误。由于版本 12.3 中有许多冻结问题,我不得不降级。一切都按预期工作,除了 realitykit 错误。 您是否对所有内容进行了清理和重建? 我在预览中遇到过类似这样的奇怪问题。您可以尝试的一件事是删除 DerivedData 中的目录。要打开您的 DerivedData 目录,请执行以下操作。 Menu Xcode - Preferences... - Locations (Tab) - Derived Data 部分点击箭头。【参考方案2】:

在 Xcode 13.2 中不再有这样的问题了!



如果您将iOS Simulator 用于基于Interface Builder Storyboard 的AR 应用程序,或者如果您使用iOS SwiftUI Preview – 那么您将无法实现面向会话的属性 并且用于 ARView 的锚定组件。如您所见,在这种情况下有很多错误。

在 Xcode Active Scheme 中选择了模拟器。

为您的 AR 应用使用面向会话的属性的唯一方法是在 Xcode Active Scheme 下拉菜单中选择真正的 iOS 或 iPadOS 设备。

选择真正的 Apple 设备进行构建。

installGestures() 方法也是如此

iOS 模拟器:

真实设备:

【讨论】:

但是使用 ARSCNView 运行良好,但不确定是什么问题 @JazKing, ARSCNView 是基于 ARKit 和 SceneKit 两种成分的共生视图,正如你所说,它运行良好。 ARSCNView 中的 ARSession(必须由开发人员设置),这里的 ARFrames 和 ARAnchors 来自 ARKit,模型 – 来自 SceneKit。然而,ARView 是一个视图,会话由 RealityKit 的应用程序自动管理,这里的任何锚点都可以更改会话的设置。 ARView 中“不能正常运行”的原因在于它的本质——Xcode 的 Simulator 不支持锚定,也不支持锚定模型的手势。 RealityKit 模型必须锚定。【参考方案3】:

我设法通过使用条件编译来消除这个问题。

#if !targetEnvironment(simulator)
    return ARView(frame: .zero)
#else
    return UIView(frame: .zero)
#endif

编译问题停止了,但我承认我仍然有预览问题。但我认为这与代码复杂性有关,而不是与此错误有关。

【讨论】:

【参考方案4】:

详细说明 Owen 的答案,我可以在 SwiftUI 中补充说,整个 UIViewRepresentable 结构都变成了编译器战区!这么多错误。 我找到了这种方法来解决它,也许它可以帮助其他人:


struct ARVideoPlayerContainer: UIViewRepresentable 
    // If I am on a real device execute my code
    #if !targetEnvironment(simulator)
    [...]
    #else
    // on the simulator execute a fake conformance to UIViewRepresentable... 
    func makeUIView(context: Context) -> UIView  UIView() 
    func updateUIView(_ uiView: UIView, context: Context) 
    #endif

【讨论】:

以上是关于ARKit 平面检测 - “ARView”类型的值没有成员“会话”的主要内容,如果未能解决你的问题,请参考以下文章

ARKit 可以将特定表面检测为平面吗?

如何在 ARKit 中检测垂直平面?

iOS增强现实(ARKit)简单介绍

如何使用 ARKit 检测触摸并显示新的 SCNPlane?

使用 ARHitTestResult 识别平面的对齐方式?

如何在 ARKit 的重建网格中获取顶点位置?