@IBOutlet var sceneVIEw: ARSCNVIEw!overrIDe func vIEwDIDLoad() { super.vIEwDIDLoad() sceneVIEw.showsstatistics = DeBUGSettings.isDeBUGActive for (index,coach) in coachpositions.enumerated() { let coachGeometry = SCNBox(wIDth: 0.1,height: 0.1,length: 0.1,chamferRadius: 0.005) let coachNode = TrainEngineNode(position: SCNVector3Make(0,float(index) * 0.1,-0.5),geometry: coachGeometry) sceneVIEw.scene.rootNode.addChildNode(coachNode) } self.sceneVIEw.autoenablesDefaultlighting = true}overrIDe func vIEwWillAppear(_ animated: Bool) { super.vIEwWillAppear(animated) // Create a session configuration let configuration = ARWorldTrackingConfiguration() // Run the vIEw's session sceneVIEw.session.run(configuration)}解决方法 正如大家所指出的那样,延迟是你在设置场景时阻塞主线程的事实.所有UI更新都发生在主线程上,并且显示刷新 60 times per second,除了可以做120Hz的最新iPad专业版.这意味着您所执行的任何同步工作单元必须在不到1/60 = 0.016667秒内完成.
您的初始化程序TrainEngineNode(position:geometry :)可能正在执行诸如从DAE或OBJ文件加载资源的工作,这可能是所有时间的所在.我这样说,因为如果你改变这一行:
let coachNode = TrainEngineNode(position: SCNVector3Make(0,geometry: coachGeometry)
为此,我需要这样做,因为你的问题中没有提供TrainEngineNode:
let coachNode = SCNNode(geometry: coachGeometry)
那么iPhone 7没有明显的延迟.
SceneKit和ARKit不要求您对任何特定线程进行更改,因此只要您遇到这种情况,您就可以将工作卸载到后台队列,或者最好是您管理的串行队列.在适当的时间进行工作有一些注意事项,例如在ARSession完全运行后将对象添加到场景中.对于创建ARKit应用程序时可能遵循的模式的一些优秀想法,我推荐Apple提供的this sample.
简化示例如下:
class SimpleARVIEwController: UIVIEwController { @IBOutlet weak var sceneVIEw: ARSCNVIEw! weak var activityIndicator: UIActivityIndicatorVIEw? var coachpositions = [1,2,3,4,5] let updateQueue = dispatchQueue(label: "com.example.apple-samplecode.arkitexample.serialSceneKitQueue") overrIDe func vIEwDIDLoad() { super.vIEwDIDLoad() sceneVIEw.Alpha = 0 vIEw.backgroundcolor = .black sceneVIEw.isPlaying = false sceneVIEw.session.delegate = self let activityIndicator = UIActivityIndicatorVIEw(activityIndicatorStyle: .whiteLarge) activityIndicator.startAnimating() activityIndicator.translatesautoresizingMaskIntoConstraints = false vIEw.addSubvIEw(activityIndicator) NSLayoutConstraint.activate([vIEw.centerXAnchor.constraint(equalTo: activityIndicator.centerXAnchor,constant: 0),vIEw.centerYAnchor.constraint(equalTo: activityIndicator.centerYAnchor,constant: 0)]) self.activityIndicator = activityIndicator sceneVIEw.autoenablesDefaultlighting = true } private func loadScene() { SCNTransaction.begin() SCNTransaction.disableActions = true for (index,_) in self.coachpositions.enumerated() { let coachGeometry = SCNBox(wIDth: 0.1,chamferRadius: 0.005) // Simulates loading time of `TrainEngineNode(position:geometry:)` usleep(500000) let coachNode = SCNNode(geometry: coachGeometry) coachNode.worldposition = SCNVector3Make(0,-0.5) self.sceneVIEw.scene.rootNode.addChildNode(coachNode) } SCNTransaction.commit() self.isLoading = false } overrIDe func vIEwWillAppear(_ animated: Bool) { super.vIEwWillAppear(animated) let configuration = ARWorldTrackingConfiguration() sceneVIEw.session.run(configuration) } overrIDe func vIEwWilldisappear(_ animated: Bool) { super.vIEwWilldisappear(animated) sceneVIEw.session.pause() } var isLoading = true var hasLoaded = false}extension SimpleARVIEwController: ARSessionDelegate { func session(_ session: ARSession,dIDUpdate frame: ARFrame) { // Waiting until after the session starts prevents objects from jumPing around if hasLoaded == false { hasLoaded = true updateQueue.async { [weak self] in self?.loadScene() } } else if isLoading == false { guard let activityIndicator = self.activityIndicator else { return } dispatchQueue.main.async { UIVIEw.animate(withDuration: 0.35,animations: { [weak self] in self?.sceneVIEw.Alpha = 1 activityIndicator.Alpha = 0 },completion: { _ in activityIndicator.removeFromSupervIEw() }) } } }}
此代码导致以下交互:
正如您在gif中看到的那样,视图控制器显示没有延迟,因为所有加载“工作”现在都在我们的专用串行队列上完成.通过将TrainEngineNode的创建与它们添加到场景的时间分离,可以进一步改善这个人为的例子.为了简洁起见,我保持逻辑与您已经拥有的逻辑类似,同时提供相对强大的初始化.对于3D对象加载的更强大/抽象的实现,我建议查看VirtualObjectLoader以及它在上述示例项目中的使用方式.
总结以上是内存溢出为你收集整理的ios – 带有ARSCNView的UIViewController在屏幕上呈现之前需要很长时间全部内容,希望文章能够帮你解决ios – 带有ARSCNView的UIViewController在屏幕上呈现之前需要很长时间所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)