如何使用情节提要停止当前模态 Segue 上的 ARView 会话?

发布于 2025-01-14 05:35:28 字数 2235 浏览 2 评论 0原文

我有两个包含 ARView 的 ViewController。代码如下:

import UIKit
import RealityKit
import ARKit

class fvBoat: UIViewController, ARSessionDelegate {
    
    @IBOutlet var arView: ARView!
    
        let fvBoatAnchor = try! Vard.loadFvBoatScene()
            var imageAnchorToEntity: [ARImageAnchor: AnchorEntity] = [:]
    
           
        override func viewDidLoad() {
                super.viewDidLoad()
            fvBoatAnchor.generateCollisionShapes(recursive: true)
            let fvBoat = fvBoatAnchor.fvBoatObject as? Entity & HasCollision
                arView.installGestures(for: fvBoat!)
                arView.scene.addAnchor(fvBoatAnchor)
                arView.session.delegate = self
        }
           
            func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
                anchors.compactMap { $0 as? ARImageAnchor }.forEach {
                    let anchorEntity = AnchorEntity()
                    let modelEntity = fvBoatAnchor.fvBoatObject!
                    anchorEntity.addChild(modelEntity)
                    arView.scene.addAnchor(anchorEntity)
                    anchorEntity.transform.matrix = $0.transform
                    imageAnchorToEntity[$0] = anchorEntity
                }
            }

            func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
                anchors.compactMap { $0 as? ARImageAnchor }.forEach {
                    let anchorEntity = imageAnchorToEntity[$0]
                    anchorEntity?.transform.matrix = $0.transform
                }
            }
            func installGestures(on object:ModelEntity){
                
                object.generateCollisionShapes(recursive: true)
                arView.installGestures([.rotation,.scale], for: object)
            }
    }

两个视图控制器的代码与上面相同。

每当我使用 Present Modally segue 导航到下一个 ARview 时,我的帧速率就会显着下降。当我转到下一个 ARview 时,如何确保 ARview 会话关闭?

ViewController 的 Storyboard 视图

也尝试添加此功能,但不确定为什么它不起作用...

func leaveScene() {

        arView?.session.pause()
        arView?.removeFromSuperview()
        arView = nil

    }

I've got two ViewControllers containing an ARView. Code is as follows:

import UIKit
import RealityKit
import ARKit

class fvBoat: UIViewController, ARSessionDelegate {
    
    @IBOutlet var arView: ARView!
    
        let fvBoatAnchor = try! Vard.loadFvBoatScene()
            var imageAnchorToEntity: [ARImageAnchor: AnchorEntity] = [:]
    
           
        override func viewDidLoad() {
                super.viewDidLoad()
            fvBoatAnchor.generateCollisionShapes(recursive: true)
            let fvBoat = fvBoatAnchor.fvBoatObject as? Entity & HasCollision
                arView.installGestures(for: fvBoat!)
                arView.scene.addAnchor(fvBoatAnchor)
                arView.session.delegate = self
        }
           
            func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
                anchors.compactMap { $0 as? ARImageAnchor }.forEach {
                    let anchorEntity = AnchorEntity()
                    let modelEntity = fvBoatAnchor.fvBoatObject!
                    anchorEntity.addChild(modelEntity)
                    arView.scene.addAnchor(anchorEntity)
                    anchorEntity.transform.matrix = $0.transform
                    imageAnchorToEntity[$0] = anchorEntity
                }
            }

            func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
                anchors.compactMap { $0 as? ARImageAnchor }.forEach {
                    let anchorEntity = imageAnchorToEntity[$0]
                    anchorEntity?.transform.matrix = $0.transform
                }
            }
            func installGestures(on object:ModelEntity){
                
                object.generateCollisionShapes(recursive: true)
                arView.installGestures([.rotation,.scale], for: object)
            }
    }

Both view controller has the same code as above.

Whenever I navigate to the next ARview using a Present Modally segue, my framerate drops significantly. How do I make sure that ARview session is closed down when I segue to the next ARview?

Storyboard view of the ViewController

Also tried adding this function, but not sure why it doesn't work...

func leaveScene() {

        arView?.session.pause()
        arView?.removeFromSuperview()
        arView = nil

    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

↘紸啶 2025-01-21 05:35:28

您并未关闭所有需要关闭的内容。

func leaveScene() {

    arView?.session.pause()
    arView?.session.delegate = nil
    arView?.scene.anchors.removeAll()
    arView?.removeFromSuperview()
    arView?.window?.resignKey()
    arView = nil
}

PS 但 arView 不会从内存中释放。

You turned off not everything that needed to be turned off.

func leaveScene() {

    arView?.session.pause()
    arView?.session.delegate = nil
    arView?.scene.anchors.removeAll()
    arView?.removeFromSuperview()
    arView?.window?.resignKey()
    arView = nil
}

P.S. But arView will not be deallocated from memory.

草莓味的萝莉 2025-01-21 05:35:28

这为我解决了这个问题。使用@Andy 的代码,我添加了leaveScene 函数,并将其称为使用UIbutton 中的发送事件:

@IBAction func leaveScene(_ sender: UIbutton) {
        leaveScene()
    }

这使我的代码如下所示。


import UIKit
import RealityKit
import ARKit

class fvBridge: UIViewController, ARSessionDelegate {
    
    @IBOutlet var arView: ARView!
    
        let fvBridgeAnchor = try! Experience.loadFvBridgeScene()
            var imageAnchorToEntity: [ARImageAnchor: AnchorEntity] = [:]
    
           
        override func viewDidLoad() {
                super.viewDidLoad()
            fvBridgeAnchor.generateCollisionShapes(recursive: true)
            let fvBridge = fvBridgeAnchor.fvBridgeObject as? Entity & HasCollision
                arView.installGestures(for: fvBridge!)
                arView.scene.addAnchor(fvBridgeAnchor)
                arView.session.delegate = self
        }
           
            func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
                anchors.compactMap { $0 as? ARImageAnchor }.forEach {
                    let anchorEntity = AnchorEntity()
                    let modelEntity = fvBridgeAnchor.fvBridgeObject!
                    anchorEntity.addChild(modelEntity)
                    arView.scene.addAnchor(anchorEntity)
                    anchorEntity.transform.matrix = $0.transform
                    imageAnchorToEntity[$0] = anchorEntity
                }
            }

            func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
                anchors.compactMap { $0 as? ARImageAnchor }.forEach {
                    let anchorEntity = imageAnchorToEntity[$0]
                    anchorEntity?.transform.matrix = $0.transform
                }
            }
            func installGestures(on object:ModelEntity){
                
                object.generateCollisionShapes(recursive: true)
                arView.installGestures([.rotation,.scale], for: object)
            }
    func leaveScene() {

        arView?.session.pause()
        arView?.session.delegate = nil
        arView?.scene.anchors.removeAll()
        arView?.removeFromSuperview()
        arView?.window?.resignKey()
        arView = nil
    }
    
    @IBAction func leaveScene(_ sender: Any) {
        leaveScene()
    }
}

This solved it for me. Using the code from @Andy I added the leaveScene function and called it as using send event from the UIbutton:

@IBAction func leaveScene(_ sender: UIbutton) {
        leaveScene()
    }

Which make my code look like this.


import UIKit
import RealityKit
import ARKit

class fvBridge: UIViewController, ARSessionDelegate {
    
    @IBOutlet var arView: ARView!
    
        let fvBridgeAnchor = try! Experience.loadFvBridgeScene()
            var imageAnchorToEntity: [ARImageAnchor: AnchorEntity] = [:]
    
           
        override func viewDidLoad() {
                super.viewDidLoad()
            fvBridgeAnchor.generateCollisionShapes(recursive: true)
            let fvBridge = fvBridgeAnchor.fvBridgeObject as? Entity & HasCollision
                arView.installGestures(for: fvBridge!)
                arView.scene.addAnchor(fvBridgeAnchor)
                arView.session.delegate = self
        }
           
            func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
                anchors.compactMap { $0 as? ARImageAnchor }.forEach {
                    let anchorEntity = AnchorEntity()
                    let modelEntity = fvBridgeAnchor.fvBridgeObject!
                    anchorEntity.addChild(modelEntity)
                    arView.scene.addAnchor(anchorEntity)
                    anchorEntity.transform.matrix = $0.transform
                    imageAnchorToEntity[$0] = anchorEntity
                }
            }

            func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
                anchors.compactMap { $0 as? ARImageAnchor }.forEach {
                    let anchorEntity = imageAnchorToEntity[$0]
                    anchorEntity?.transform.matrix = $0.transform
                }
            }
            func installGestures(on object:ModelEntity){
                
                object.generateCollisionShapes(recursive: true)
                arView.installGestures([.rotation,.scale], for: object)
            }
    func leaveScene() {

        arView?.session.pause()
        arView?.session.delegate = nil
        arView?.scene.anchors.removeAll()
        arView?.removeFromSuperview()
        arView?.window?.resignKey()
        arView = nil
    }
    
    @IBAction func leaveScene(_ sender: Any) {
        leaveScene()
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文