Ios ARKit会话已暂停,无法继续
在我的ARKit应用程序中,我演示了一个模式窗口。当我关闭模式并返回ARSCNView时,我发现会话因以下代码而暂停:Ios ARKit会话已暂停,无法继续,ios,arkit,Ios,Arkit,在我的ARKit应用程序中,我演示了一个模式窗口。当我关闭模式并返回ARSCNView时,我发现会话因以下代码而暂停: override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // Pause the view's session sceneView.session.pause() } 当我关闭模式并返回ARKit c
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Pause the view's session
sceneView.session.pause()
}
当我关闭模式并返回ARKit camera view屏幕时,会触发以下代码:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a session configuration
let configuration = ARWorldTrackingSessionConfiguration()
// Run the view's session
sceneView.session.run(configuration)
}
但此代码从不恢复会话。屏幕在最后读取的图像上完全冻结。有什么想法吗
我将viewdide代码更新为以下代码。它仍然停留在相机屏幕上,图像冻结
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a session configuration
let configuration = ARWorldTrackingSessionConfiguration()
sceneView.session.delegate = self
if self.isPaused {
sceneView.session.run(sceneView.session.configuration!)
} else {
// Run the view's session
sceneView.session.run(configuration)
}
}
不确定您的会话为什么没有恢复,但是。。。这通常不是你想要的情况 请注意自述文件中随附的苹果ARKit示例代码(附于附件): 避免中断AR体验。如果用户切换到应用程序中的另一个全屏UI,则返回时AR视图可能不是预期状态 为辅助视图控制器使用popover演示(甚至在iPhone上),在调整设置或进行模式选择时让用户保持AR体验。在本例中,
SettingsViewController
和VirtualObjectSelectionViewController
类使用popover表示
更详细地说:如果您暂停会话,当您的用户在不同的全屏视图控制器中时,它将不会跟踪世界。这意味着当你恢复时,场景中的任何虚拟内容都不会位于你离开它的位置(相对于相机)。我知道你已经选择了一个答案,而这个答案是苹果公司推荐的,你可以重新启动AR会话。但是,您不能取消暂停/恢复会话,因为一旦您离开控制器,设备将停止跟踪,并显示ARSceneView,并且将停止跟踪设备相对于场景中放置的对象的位置 无论如何,我已经设法重新启动会话,基本上是通过销毁会话的所有方面,并在视图重新出现时重建它们,或者通过按下按钮 我将在这里发布一些示例代码。这是用Objective-C写的,因为我的项目就是用它写的,但它可能会帮助未来的人解决同样的问题
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated]
[self setupScene];
[self setupSession];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self destroySession];
[self destroyScene];
}
- (void)setupScene {
// Setup the ARSCNViewDelegate - this gives us callbacks to handle new
// geometry creation
self.sceneView.delegate = self;
// A dictionary of all the current planes being rendered in the scene
self.planes = [NSMutableDictionary new];
// Contains a list of all the boxes rendered in the scene
self.boxes = [NSMutableArray new];
// Show statistics such as fps and timing information
self.sceneView.showsStatistics = YES;
self.sceneView.autoenablesDefaultLighting = YES;
SCNScene *scene = [SCNScene new];
[self.sceneView setScene:scene];
self.sceneView.scene.physicsWorld.contactDelegate = self;
}
- (void)setupSession {
// Create a session configuration
ARWorldTrackingConfiguration *configuration = [ARWorldTrackingConfiguration new];
//ARWorldTrackingSessionConfiguration *configuration = [ARWorldTrackingSessionConfiguration new]; This has been deprecated in favor of the previous line in XCode 9 beta 5.
// Specify that we do want to track horizontal planes. Setting this will cause the ARSCNViewDelegate
// methods to be called when scenes are detected
//configuration.planeDetection = ARPlaneDetectionHorizontal;
// Run the view's session
[self.sceneView.session runWithConfiguration:configuration options:ARSessionRunOptionResetTracking];
}
-(void)destroyScene {
bottomPlane = nil;
[self.sceneView setScene:nil];
[self.sceneView setDebugOptions:nil];
self.boxes = nil;
self.planes = nil;
self.sceneView.delegate = nil;
}
-(void)destroySession {
[self.sceneView.session pause];
[self.sceneView setSession:nil];
}
这些销毁方法在视图消失时使用。我也通过按下按钮重新启动AR会话,但不是通过这些方法。详情如下:
-(void)resetPressed{
NSLog(@"Reset Pressed");
[_sceneView.session pause];
SCNScene *scene = [[SCNScene alloc] init];
[_sceneView setScene:scene];
[_sceneView.scene.rootNode enumerateChildNodesUsingBlock:^(SCNNode * _Nonnull child, BOOL * _Nonnull stop) {
[child removeFromParentNode];
}];
ARWorldTrackingConfiguration *configuration = [[ARWorldTrackingSessionConfiguration ARWorldTrackingConfiguration] init];
[_sceneView.session runWithConfiguration:configuration options:ARSessionRunOptionResetTracking | ARSessionRunOptionRemoveExistingAnchors];
}
希望有帮助。我不知道iOS 11 GM-Seed或XCode 9 GM-Seed版本今天是否解决了这个问题,但是我可以成功地恢复暂停的ARSCNview,代码与原始问题相同
sceneView.session.run(sceneView.session.configuration!)
以下是使用Swift 4.2和iOS 12的答案 要在AR场景上显示另一个视图控制器中定义的UI,请创建视图控制器实例,并将其
modalPresentationStyle
属性设置为。overCurrentContext
:
EXAMPLE:
func showMaterialPicker(completion: (Texture?) -> Void) {
// create an instance of your view controller, I have convenience functions
// setup to do this via an extension on UIViewController
guard let materialPicker = MaterialCategoriesViewController.instance(from: .product) else {
print("Unable to instantiate MaterialCategoriesViewController, bailing")
return
}
// set presentation style and transition style
materialPicker.modalPresentationStyle = .overCurrentContext
materialPicker.modalTransitionStyle = .crossDissolve
// present the controller
present(materialPicker, animated: true, completion: nil)
}
奖金提示:
要使覆盖层看起来像抽屉一样从底部向上滑动,请设置
materialPicker.modalTransitionStyle = .coverVertical
然后将覆盖视图控制器中的视图从底部约束到合适的高度,并将视图控制器视图的背景色设置为UIColor.clear
如果要在显示覆盖时使AR视图变暗,可以将背景色设置为黑色,不透明度/alpha值约为0.75
大概是这样的:
self.view.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.75)
或者在故事板中:
在上面的屏幕截图中,我在叠加视图控制器视图的底部和侧面固定了一个tableview,高度限制为300
这样做后,您仍然可以看到叠加视图控制器后面的AR视图,场景继续渲染。谢谢@rickster!现在有道理了。我会确保用户不会离开AR体验而使用popover演示文稿。即使在使用popover演示文稿时,我也会看到会话被冻结。可能的错误?被接受的答案还说,他们无法重现这个问题,并进一步详述。这个答案可以被编辑以增加OP和其他关于这个问题的人的价值吗?这对我来说非常有用!首先是self.sceneView.session.pause(),然后是sceneView.session.run(sceneView.session.configuration!),这就是我一直在做的事情。但不知何故,如果长时间丢失帧,则会创建环绕ARSession的第二次。摄像机状态无限期地停留在ARTrackingStateLimited。我不太明白你是如何处理世界中心坐标的变化的。最有可能的是,在你第二次主持会议时,世界将不在同一个中心。因此,所有加载的节点都将放错位置。你能为我提供一个解决这个问题的方法吗?因为我能想到的只是一些图像识别软件,它能以某种方式转换世界中心的变化,并从中给出一个转换矩阵。有更好的建议吗?@dvp.petrov我不是在讨论坐标的变化。我只是简单地解决了问题中的问题,即当OP返回到AR视图控制器时,AR会话被暂停并且没有移动。我只是提供了一种方法,一旦您返回到视图控制器,就可以重新启动会话。关于你的问题,我想你可以保存你添加的所有节点的位置,并在回来后重新添加它们,但不能保证设备在那一点上会处于相同的物理位置。@AlanS-我很好奇,你第二次运行ARSession时,它是否和第一次一样稳定?在我的第二次运行中,我将它永远作为ArtrackingStateReasonInitialization,并且它永远不会成为ARTrackingStateReasonNone。最后!两天后,我可以说,这就是成功的原因!事实上,我有一点不同的问题。当我在SceneViewController上显示一个NewViewController时,这个NewViewController冻结了。我尝试过暂停、恢复会话、完全删除场景并重新初始化ViewWillAppease,但没有任何效果。只有我是通过@di看到这篇文章的