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作業のスタイルと品質が決まります。
- A9以降のプロセッサを搭載したデバイスでは、
ARWorldTrackingSessionConfiguration
を使用できます。 この構成により、新しいフレームワークの力を最大限に活用できます。 仮想現実の周囲の世界のモデルが作成され、カメラの視野内の平面に関する情報が提供されます。 これにより、仮想オブジェクトを最大限の精度で配置できます。 - ARKitをサポートする他のデバイスでは、ARSessionConfigurationのみが使用可能になります。 基本クラスは、空間内のデバイスの動きに関する情報のみを提供しますが、仮想モデルは構築しません。 これは望ましい効果を与えず、新しい技術のすべての品質を享受することはできません。 実際のオブジェクトに関連する仮想オブジェクトを修正することはできません。
構成のタイプを選択したら、そのインスタンスを作成し、構成してセッションを開始する必要があります。
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月に近づくでしょう。