sceneView.delegate 和 sceneView.session.delegate 有什么区别?

What is the difference between sceneView.delegate and sceneView.session.delegate?

我正在阅读下面的代码。

https://github.com/tukuyo/rakumaruCardMan/blob/master/rakutencard-Man/ViewController.swift

    sceneView.delegate = self
    sceneView.session.delegate = self

代码在没有 sceneView.delegate = self 的情况下无法运行,但 sceneView.session.delegate = self 即使注释掉也似乎可以正常运行。

那么写sceneView.session.delegate = self?

的原因是什么

sceneView 委托的类型为 ARSCNViewDelegate, while the session delegate is of type ARSessionDelegate. As you can see in the documentation, they provide different information through their methods, but they also provide some overlapping functionality, since both extend ARSessionObserver

只有在使用 ARSCNView 时才需要实施 ARSCNViewDelegate,链接项目就是这种情况。此委托提供的大多数方法都与渲染器 (SceneKit) 显示的对象的更新有关。因此,当您使用 ARSCNView 时,SceneKit 和 ARKit 是捆绑在一起的。当 ARKit session (sceneView.session) 更新时,渲染器会收到通知,然后更新,触发来自 ARSCNViewDelegate 的方法。例如,当 ARKit 添加锚点并创建与该锚点关联的节点时,将调用 renderer(_:didAdd:for:)

至于 ARSessionDelegate,当您需要了解会话中的锚点变化时,或者当新帧从相机馈送到达时,您会想要实施它。这些更新不依赖于任何渲染器。这意味着您可以使用不同的渲染器(例如 Metal)来实现这些方法。您只需要创建一个 ARSession 对象并设置其委托。

由于这两个协议都从 ARSessionObserver, I would say that you will almost always implement only ARSCNViewDelegate when you're using an ARSCNView. The only method that could possibly benefit you from ARSessionDelegate is session(_:didUpdate:) 扩展而来,它会通知您有关帧更新的信息,而且 ARSCNViewDelegate 中似乎没有等效项。至于锚点更新,它们将反映在 ARSCNViewDelegate 上,因为 SceneKit 将根据 ARKit 事件更新其场景。

最后一件事:ARSCNView 只是 Apple 提供的便利 class,因此您已经将 ARKit 与 SceneKit 渲染器绑定,但您仍然可以实现自己的 ARSession 与自定义 SCNScene.