LoginSignup
59
50

More than 5 years have passed since last update.

ネイティブ未経験からARKitを習得する3ヵ月

Last updated at Posted at 2019-04-22

はじめに

私はBackendエンジニアです。
ARはもとよりネイティブアプリを一から作ることは全くの未経験でした。
そんな状況でARアプリを作るには・・・という3ヵ月で得た知見を記します。

3ヵ月の内訳

期間 担当範囲 スキル状況
担当前 - Swiftはコードリーディング程度で、3Dの知識も"右手の法則・・・?"レベル
1ヵ月目 ネイティブアプリエンジニアにベースを作ってもらい、なんとなくで継接いでいく マーカー型の機能を使い、認識したマーカーの真上にオブジェクトを置くことが出来る
2ヵ月目 座標共有機能(ARWorldMap+MultiPeerConnectivity)を使った端末間の座標を共有したアニメーション機能 Apple Developer DocumentやApple提供のSampleCodeを読みながらAR特有の機能を実装出来る
3ヵ月目 平面検知からオブジェクト配置、別のオブジェクトを相対位置に配置し、2つのオブジェクトを相互にアニメーションさせる機能 平行移動をある程度理解して実装出来る
延長2週間 新規ARアプリを一から担当 ARアプリを独力で実装出来る

AR概略

ARについて

  • 拡張現実(Augmented Reality)
  • 現実世界をコンピューティングで拡張する技術

最近はスマホのカメラ使ってたら大体ARだと思っています。

主要技術

技術 詳細 備考
位置認識 機器のセンサーを使い、現実世界の位置を仮想世界の座標に落とし込む
マーカー 事前に定義したマーカーを現実世界から検出し、座標を求める 画像検出・立体検出
マーカーレス 現実世界の物質を検出し、座標を求める 平面検出・垂直平面検出
その他 - 顔認識など

周辺技術

名称 概要
ARToolkit 奈良先端科学技術大学院大学の加藤博一教授によって開発されたC言語ライブラリ
wikiより
ARKit iOS用ライブラリ
ARCore Android用ライブラリ
Unity 3Dゲームエンジンだが、ARKit・ARCoreをサポートしている
AR.js javascriptOSS
マーカー型onlyのため注意
その他 いろいろある

ARKitについて

用意するもの

これだけ用意出来ればARKitを使ったアプリを作れます。

  • Mac & Xcode
  • iPhone(6s以上の端末)
  • AppleID

ARKit対応端末はこちら

ARKitを習得するための難易度別解説

初心者編 ~基礎知識が無くてもセンスで出来るレベル~

ARしてみる

iOSアプリはXCodeのテンプレートプロジェクトを使うのが初めの一歩です。
テンプレートには「Augmented Reality App」があるので、それを選択しましょう
ビルドするだけで飛行機の3Dオブジェクトが目の前に登場することになります。

TemplateProject ビルド後

マーカーを使ってARしてみる

  1. マーカー(画像)を登録する
    AssetsにAR ResourceGroupを追加
    AR ReferenceImageを設定。physical sizeを設定。
  2. マーカーを認識したらアクション(飛行機を出現)する

画像認識処理を実装する

override func viewWillAppear(_ animated: Bool) {
  let configuration = ARWorldTrackingConfiguration()
  let images = ARReferenceImage.referenceImages(
    inGroupNamed: "AR Resources", bundle: nil)
  configuration.detectionImages = images
  configuration.planeDetection = [.vertical, .horizontal]

  sceneView.session.run(configuration)
}

ARImageTrackingConfigurationでもよいのですが、後々現実空間の座標を使うことになるのでARWorldTrackingConfigurationを推奨します。
状態によってマーカーを切り替えたい場合はinGroupNamed:AR ResourceGroupの名称に合わせます。

認識した位置に飛行機を出す

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
  if let anchor = anchor as? ARImageAnchor {
    let ship = SCNScene(
      named: "ship.scn", inDirectory: "art.scnassets"
    )!
    for node in ship.rootNode.childNodes {
      node.simdTransform = anchor.transform
      sceneView.scene.rootNode.addChildNode(node)
    }
  }
}

rendererはARセッションがマーカーまたは平面等を検出した際に実行されるメソッドです。
オブジェクトにアンカーの座標を設定することを忘れずに。

中級者編 ~公式ドキュメントを読めば実装出来るレベル~

3Dオブジェクトを作る

2種類の方法があります

  1. Scene Editorを使う

    ProjectにSceneFileを追加することでSceneEditorを使って3Dオブジェクトを作れます。
    参考:AppleDeveloperVidelos: wwdc2015
       ※5:00頃から。
  2. ソースコードからSceneKitを使う
let box = SCNBox(
  width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
box.firstMaterial?.diffuse.contents =
  UIColor(red: 0, green: 0, blue: 1.0, alpha: 1.0)
let node = SCNNode(geometry: box)
sceneView.scene.rootNode.addChildNode(node)

上記はシンプルな立方体。

要求によって検出設定周りを使い分ける

コンフィギュレーション 概要
ARWorldTrackingConfiguration 現実世界(全部)をトラッキング
ARImageTrackingConfiguration 2D画像だけトラッキング
ARObjectScanningConfiguration 3Dオブジェクトだけトラッキング
ARFaceTrackingConfiguration 顔だけトラッキング

汎用性はARWorldTrackingConfigurationが一番高いので、まずはこれを使うことが多いです。

シンプルなアニメーションを付ける

SCNActionを使います

種類 メソッド
移動 SCNAction.move(by: SCNVector3(1,1,1), duration: 1)
SCNAction.move(to: SCNVector3(1,1,1), duration: 1)
回転 SCNAction.rotateBy(x: 1, y: 1, z: 1), duration: 1)
SCNAction.rotateTo(x: 1, y: 1, z: 1), duration: 1)
拡大 SCNAction.scale(by: 1, duration: 1)
SCNAction.scale(to: 1 duration: 1)

上級者編 ~3D数学を学べば実装出来るレベル~

オブジェクトの隣にオブジェクトを置く

newNode.setWorldTransform(SCNMatrix4Translate(
  node.worldTransform,
  node.boundingBox.max.x,
  0,
  0
))

SCNMatrix4Translate:4x4行列を平行移動変換し、新しい行列を返します。
worldTransform:nodeのワールド座標を4x4行列で返します。
boundingBox.max.x:nodeの中心座標から最大のx座標までの距離を返します。

3Dオブジェクトを動的に変形する

let box = SCNBox(
  width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
let redMaterial = SCNMaterial()
redMaterial.diffuse.contents =
  UIColor(red:1, green:0, blue: 0, alpha: 1)
let blueMaterial = SCNMaterial()
blueMaterial.diffuse.contents =
  UIColor(red: 0, green: 0, blue: 1.0, alpha: 1.0)
box.materials = [redMaterial, blueMaterial]

SCNBoxのマテリアル(面)に赤と青のTextureを貼り付ける。

おわりに

0ヵ月目の私は「ARって相当難しい技術を使うんでしょ・・・」と滅入っていましたが、ここでまとめた 初心者編 さえ身に着ければ ARは作れます。
≒ ARは簡単です。
難しいのは3Dデザイン(SceneKit)です。

当時夜な夜な参考にさせていただきました。感謝。

59
50
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
59
50