我正在阅读下面的代码。

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,而session委托的类型为ARSessionDelegate。如您在文档中所看到的,它们通过它们的方法提供了不同的信息,但是它们也提供了一些重叠的功能,因为它们都扩展了ARSessionObserver

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

至于ARSessionDelegate,当您需要了解 session 中的锚点更改或从摄像机源获取新帧时,将需要实现它。这些更新未绑定到任何渲染器。这意味着您可以使用其他渲染器(例如Metal)来实现这些方法。您只需要创建一个ARSession对象并设置其委托即可。

由于这两个协议都是从ARSessionObserver扩展而来的,所以我想说,当您使用ARSCNViewDelegate时,几乎总是只实现ARSCNView。可以从ARSessionDelegate中受益的唯一方法是session(_:didUpdate:),它会通知您有关帧更新的信息,而且ARSCNViewDelegate中似乎没有等效的方法。至于锚点更新,它们将反映在ARSCNViewDelegate上,因为SceneKit将基于ARKit事件更新其场景。

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

10-08 12:12