2017-07-07 17 views
5

私のARKitアプリケーションでは、モーダルウィンドウを表示しています。私はモーダルを閉じてARKitカメラビュー画面に戻るときARKitセッションが一時停止し、再開しない

override func viewWillDisappear(_ animated: Bool) { 
     super.viewWillDisappear(animated) 

     // Pause the view's session 
     sceneView.session.pause() 
    } 

は、このコードがトリガーされます:私はモーダルを閉じて戻ってARSCNViewに行くとき、私はセッションが原因このコードに一時停止していることを見つけます:

override func viewWillAppear(_ animated: Bool) { 
     super.viewWillAppear(animated) 

     // Create a session configuration 
     let configuration = ARWorldTrackingSessionConfiguration() 

     // Run the view's session 
     sceneView.session.run(configuration) 
    } 

しかし、このコードはセッションを再開しません。最後に読み込んだ画面で画面が完全にフリーズします。何か案は?

私は、次のようにviewDidAppearコードを更新します。それはまだ画像が凍っているとカメラの画面に固執しています。

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) 
     } 


    } 

答えて

5

あなたのセッションが再開しない理由はわかりませんが...これは一般的にあなたが欲しい状況ではありません。その(WWDC17 session on ARKitに添付)AppleのARKitサンプルコードに付属のreadmeで

お知らせ:AR体験を中断

は避けてください。ユーザーがアプリで別のフルスクリーンUIに移行した場合、戻ったときにARビューが期待どおりの状態にならないことがあります。

は、設定を調整するか、モーダル選択をしながらAR体験でユーザーを維持するために補助ビューコントローラ用(でもiPhone上)ポップオーバーのプレゼンテーションを使用してください。この例では、SettingsViewControllerVirtualObjectSelectionViewControllerクラスはpopoverプレゼンテーションを使用します。

さらに詳しく説明すると、セッションを一時停止すると、ユーザーが別のフルスクリーンビューコントローラーにいない間に世界をトラッキングすることはありません。つまり、再開すると、シーンに配置された仮想コンテンツは、そのシーンを離れた場所(カメラを基準にした位置)に表示されません。

+0

ありがとう@rickster!今や意味をなさない私は、ユーザーがARエクスペリエンスを離れてポップオーバープレゼンテーションを使用しないようにします。 –

+0

私は、ポップオーバープレゼンテーションを使用していてもセッションがフリーズしているのを見ています。考えられるバグ? https://forums.developer.apple.com/thread/81943 –

1

は、私はあなたが答えを選択したことを取得し、その答えは、アップルが推奨しているものである、あなたは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]; 
} 

希望します。

+0

これは私がやっていることです。しかし、何らかの形で、ARSessionの周りの2回目は、フレームが長時間にわたって欠落している場合に作成されます。カメラの状態はARTrackingStateLimitedに無制限にとどまります。 – nishant

+0

世界の中心座標の変化にどのように取り組んでいるのかよく分かりません。ほとんどの場合、2回目のセッションを実行するときに、同じセンターには世界が存在しない可能性があります。したがって、ロードされたノードはすべて置き換えられます。何とか世界の中心の変化を何らかの形で翻訳し、そこから翻訳マトリックスを与えることができるImageRecognitionソフトウェアが私に思いつきますので、この問題の解決策を教えてください。より良い提案はありますか? –

+0

@ dvp.petrov私は座標の変更に取り組んでいません。この質問の問題を解決するには、OPがAR View Controllerに戻ったときにARセッションが一時停止され、移動しないという問題でした。そのビューコントローラに戻ったら、セッションを再開する方法を提供していました。 あなたの質問に関しては、あなたが追加したすべてのノードの位置を保存して戻ってくるとそれらを再追加することができますが、デバイスが同じ物理的な場所にあるという保証はありませんポイント。 –

1

iOSの11 GM種子やXCodeの9 GM種子のバージョンは、しかし、私は成功し、元の質問のようにコードを一時停止ARSCNviewを再開することができ、この今日の固定場合、私は知りません。

sceneView.session.run(sceneView.session.configuration!) 
+0

答えには、問題を再現できず、さらに詳しく説明されているという回答もあります。この問題を解決するために、この回答を編集してOPその他の人たちに価値をもたらすことができますか? – stealththeninja

+0

これは私にとって素晴らしい仕事でした!最初にself.sceneView.session.pause()を実行すると、sceneView.session.run(sceneView.session.configuration!) – Jordan

関連する問題