ARKit機能のテスト。 拡張現実ゲームの作成

画像







WWDC 2017で、Appleは拡張現実SDKであるARKitを発表しました。 彼のおかげで、この技術を導入するためのしきい値ははるかに低くなりました。 多数の高品質のゲームとアプリケーションの出現が期待できます。







基調講演を見たなら、おそらくあなたはあなたが見たものにすでに喜んでいるでしょう。 AppleのエンジニアがARKitを使用して通常のテーブルに展開することができたゲームの世界は、最も洗練されたゲーマーでさえも無関心ではありません。 それは単なるプロトタイプではなく、実際に機能する適切に機能するテクノロジーでした。 これは、いくつかのデモを実行するか、自分たちの世界に仮想物を持ち込もうとすることで簡単に確認できます。







iPhone 6以下の幸運な所有者を怒らせる必要があります。 これらのデバイスでは、これらすべての生命の魅力にアクセスできなくなります。 ARKitのすべての主要機能を使用するには、A9以上のプロセッサが必要です。 もちろん、Appleは機能へのアクセスを制限しますが、そうではありません。







拡張現実



拡張現実(拡張現実、AR)は、現実世界に重ねて表示される仮想環境であり、より表現力豊かで有益なものにしたり、単に楽しいものにしたりします。 この用語は、1990年にボーイングの研究者Thomas Codellによって提案されたと言われています。 それでも、この技術を使用したデバイスの最初の例が現れ始めました。 飛行情報とレーダー情報を表示するために、パイロットの電子ヘルメットに拡張現実初めて実装されました







ほぼ20年にわたって何をしてきたのか、なぜこの技術が今だけ大規模な開発を受けたのかを聞きたいと思います。 すべてが非常に簡単です。 電話、センサー、およびコンピュータービジョンテクノロジーの開発に優れたカメラが登場したことで、これが可能になりました。







AppStoreの棚で何が便利になり、近い将来に何が期待できますか? 実際、すべては開発者の想像力によってのみ制限されます。 ARがAppleの新しいフレームワークのリリースに革命をもたらすいくつかの業界を自信を持って挙げることができます。









ARKitの機能



ARKitはHarry Potterの魔法の杖ではなく、デバイスから受信した大量のデータを正しく処理できるツールです。 カメラとモーションセンサーのおかげで、フレームワークは動きを監視し、表面を見つけて照明を決定します。 データを分析した後、交点、表面座標、空間内のカメラの位置という形で周囲の世界の具体的なアイデアを得ることができます。







ARKitの主な目的は、周囲の世界を追跡(ワールドトラッキング)して、現実世界の仮想モデルを作成することです。 フレームワークはビデオフレームの機能を認識し、その位置の変化を追跡し、この情報をモーションセンサーからのデータと比較します。 結果は、現実世界の仮想モデルです。 別の機能は、平らな水平面の認識です。 ARKitは飛行機を見つけ、その場所とサイズを報告します。







外の世界を追跡するには、カメラから受け取った画像の分析が必要です。 最良の結果を得るには、適切な照明が必要です。







ARKitの基礎はARSCNView



ARSKView



です。 ライブビデオを表示し、3Dおよび2D画像をレンダリングします。 誰もがすでに推測しているように、これらはSCNView



SKView



からの相続人SKView



。 したがって、ARKitはデータの表示に信じられないほどの機能をもたらしません。 これらはすべて2Dおよび3Dグラフィックスを操作するための同じエンジンであり、誰もが既に使い慣れているものです。 したがって、このテクノロジーを導入するためのしきい値は非常に低くなります。 Appleはテクノロジーと製品への愛で有名ですが、それにもかかわらず、ARKitの開発者はUnityとUnreal Engineをサポートしました。 これは、近い将来登場する高品質のアプリケーションの数にプラスの影響を与えます。







ARSCNView



ARSKView



は、ARKit- ARSession



中心が含まれています。 拡張現実での作業に必要なすべてを含むのはこのクラスです。 ARSession



を開始するには、セッションの構成を転送する必要があります。







構成のタイプによって、達成できるAR作業のスタイルと品質が決まります。









構成のタイプを選択したら、そのインスタンスを作成し、構成してセッションを開始する必要があります。







 override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Create a session configuration let configuration = ARWorldTrackingSessionConfiguration() // Run the view's session sceneView.session.run(configuration) }
      
      





ARKitは計算にかなりのエネルギーを消費することを覚えておくことが重要です。 コンテンツを含むビューが現在画面に表示されていない場合、 session.pause()



を使用してこの時間のセッションを一時停止することは理にかなっています。







セッションを開始した後、仮想コンテンツの操作を開始できます。 ARKitにプレーンを認識さplaneDetection



場合は、構成のplaneDetection



値を必ずplaneDetection



に設定してplaneDetection



。 水平面の認識は、最初は無効になっています。 将来、垂直面を見つけることができるようになることを期待しましょうが、これまでは水平面のみです。







環境情報を取得する方法は、 ARSCNView



ARSKView



またはMetal



を使用するデータ表示の種類によって異なります。 ARKitが提供する情報の単位はARAnchor



です。 表面認識を有効にしている場合、サブクラスARPlaneAnchor



ます。 見つかったプレーンに関する情報が含まれています。 これらのアンカーのおかげで、宇宙をナビゲートすることが可能です。 Metalを使用する場合は、手動でレンダリングする必要があります。 その後、 ARSessionDelegate



クラスのARSessionDelegate



デリゲートを使用して更新をサブスクライブし、セッションからアンカーを受け取ることができます。 オブジェクトのレンダリングにAppleエンジンの1つを使用する場合、より便利なデリゲートARSCNViewDelegate



またはARSKViewDelegate



を使用する機会があります。







一見、すべてが非常に簡単です。 ほとんどすべての苦労はARSession



によって行われARSession



。 テストアプリケーションを作成してみましょう。







ARKit機能のテスト



拡張現実は、現在、ゲーム業界の市場を爆発させたゲームPokémonGOに関連付けられています。 同様のことを試してみましょう。







テストアプリケーションを作成するには、 ARSCNView



を使用して3Dモデルを作成およびレンダリングします。 ゲームは2つのステージで構成されます。 最初に、部屋の周りにターゲットを設定し、それからできるだけ早くそれらすべてにヒットするようにします。 ゲームはかなり原始的ですが、拡張現実を備えたゲームを作成するシンプルさを実証します。







まず、ViewController ARSCNView



全体を拡張し、 ARSCNView



を作成することから始めましょう。 さらに、通常のSCNView



と同様に、それを使用します。 初期設定をしましょう。 コントローラを物理世界の連絡先のデリゲートにし、統計を表示します。 コントローラーの表示と非表示を切り替えるときのセッションの開始と一時停止を構成します。







 override func viewDidLoad() { super.viewDidLoad() sceneView.scene.physicsWorld.contactDelegate = self // Show statistics such as fps and timing information sceneView.showsStatistics = true } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Create a session configuration let configuration = ARSessionConfiguration.isSupported ? ARWorldTrackingSessionConfiguration() : ARSessionConfiguration() // Run the view's session sceneView.session.run(configuration) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // Pause the view's session sceneView.session.pause() }
      
      





セッション構成の選択は、アプリケーションが起動されたデバイスのモデルによって異なります。 このチェックを行うことが不可欠です。 そうしないと、設定が正しくない場合、セッションはエラーを送信し、ゲームはまったく起動しません。







ARKitは非常に単純なので、その設定は一切使用しません。 まだ必要なのは、仮想世界の空間内のカメラの位置です。 残りは技術の問題であり、SceneKitの一部です。







ここでは、クリック処理やスコアリングについては説明しません。 これはそれほど重要ではなく、記事の最後にあるデモで自分で確認できます。







このゲームには、2つのモデルのオブジェクトが含まれています。撮影するボールと、Touch Instinctの飛行ロゴです。 これらのモデルを画面に追加するには、 SCNNode



を使用して作成する必要があります。







物理オブジェクトを作成するために必要なもの:









ボールの形のカートリッジクラスと、希望のテクスチャを備えたキューブの形のロゴの実装例。







 class ARBullet: SCNNode { override init() { super.init() let arKitBox = SCNSphere(radius: 0.025) self.geometry = arKitBox let shape = SCNPhysicsShape(geometry: arKitBox, options: nil) self.physicsBody = SCNPhysicsBody(type: .dynamic, shape: shape) self.physicsBody?.isAffectedByGravity = false self.physicsBody?.categoryBitMask = CollisionCategory.arBullets.rawValue self.physicsBody?.contactTestBitMask = CollisionCategory.logos.rawValue // add texture let material = SCNMaterial() material.diffuse.contents = UIImage(named: "art.scnassets/ARKit_logo.png") self.geometry?.materials = [material] } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
      
      





 class Logo: SCNNode { override init() { super.init() let logo = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0) self.geometry = logo let shape = SCNPhysicsShape(geometry: logo, options: nil) self.physicsBody = SCNPhysicsBody(type: .dynamic, shape: shape) self.physicsBody?.isAffectedByGravity = false self.physicsBody?.categoryBitMask = CollisionCategory.logos.rawValue self.physicsBody?.contactTestBitMask = CollisionCategory.arBullets.rawValue // add texture let material = SCNMaterial() material.diffuse.contents = UIImage(named: "art.scnassets/logo-mobile.png") self.geometry?.materials = Array(repeating: material, count: 6) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
      
      





CollisionCategoryに注目したいと思います。 この構造は、接触しているオブジェクトのタイプを判別するために使用されます。







 struct CollisionCategory: OptionSet { let rawValue: Int static let arBullets = CollisionCategory(rawValue: 1 << 0) static let logos = CollisionCategory(rawValue: 1 << 1) }
      
      





これは、連絡先を決定するための標準的な戦術です。 categoryBitMask



プロパティは、特定のオブジェクトのマスクを設定し、 contactTestBitMask



は、私たちが関心を持ち、通知を受けるすべての連絡先を設定します。







コンタクト処理について話しているので、コントローラーでどのように見えるかを見てみましょう。 viewDidLoad



、物理世界の接触イベントに既にサブスクライブしています。 1つの機能を実装することは残ります。







 extension ViewController: SCNPhysicsContactDelegate { func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) { guard let nodeABitMask = contact.nodeA.physicsBody?.categoryBitMask, let nodeBBitMask = contact.nodeB.physicsBody?.categoryBitMask, nodeABitMask & nodeBBitMask == CollisionCategory.logos.rawValue & CollisionCategory.arBullets.rawValue else { return } contact.nodeB.removeFromParentNode() logoCount -= 1 if logoCount == 0 { DispatchQueue.main.async { self.stopGame() } } DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: { contact.nodeA.removeFromParentNode() }) } }
      
      





最も興味深いのは、立方体の形でカートリッジとターゲットの衝突が発生した最初のチェックです。 ビットマスクに基づいています。 これは非常に便利で、他の多くのチェックが不要になります。







衝突では、残りのロゴのカウンターを減らし、両方のオブジェクトを削除します。 2番目のオブジェクトは、衝突を視覚化するために少し遅れて削除されます。







2つの主なゲーム機能は、ターゲットとショットの追加です。 追加は、カメラが向けられている側の画面からわずかな距離で行われます。 構成済みのキューブオブジェクトを作成し、シーンに追加して、空間内のカメラに対する位置を調整します。







 private func addLogo() { guard let currentFrame = sceneView.session.currentFrame else { return } let logo = Logo() sceneView.scene.rootNode.addChildNode(logo) var translation = matrix_identity_float4x4 translation.columns.3.z = -1 logo.simdTransform = matrix_multiply(currentFrame.camera.transform, translation) logoCount += 1 if logoCount == ViewController.logoMaxCount { startGame() } }
      
      





発射されると、ボールオブジェクトも作成されます。 シーンに追加します。 しかし、今では追加するだけでなく、高速化する必要があります。 これを行うために、画面の中央の位置を決定し、正しい方向に力を加えることで加速します。







 private func shoot() { let arBullet = ARBullet() let (direction, position) = cameraVector arBullet.position = position arBullet.physicsBody?.applyForce(direction, asImpulse: true) sceneView.scene.rootNode.addChildNode(arBullet) }
      
      





そのため、ほんの数十行で、簡単なゲームを作成しました。







未来は9月に来る



ご覧のとおり、Appleは素晴らしい仕事をしました。 新しいARKitフレームワークのおかげで、拡張現実アプリケーションの作成は、複数のコントローラーを使用してアプリケーションを作成するのと同じくらい簡単です。 この場合、美しい景色を心配する必要はありません。 このテクノロジーは、モバイルアプリケーションの理解を確実に変えるでしょう。







新しいXcode 9をダウンロードして、私たちの世界に仮想の魔法を追加するアプリケーションを作成してください。 未来はここにあります。 さて、さもなければ、Appleの次のプレゼンテーションの後、9月に近づくでしょう。







デモプロジェクト



Touch Instinctリポジトリにダウンロードする










All Articles