122
97

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ARKitAdvent Calendar 2018

Day 20

ARKitで作るAR名刺

Last updated at Posted at 2018-12-19

ARKitで作る名刺といえば、なんと言っても彼のコンセプト動画です。

これは感動しましたね。。!情報が無限大じゃんと思いました。そこで僕も簡単にですが、同じようなものをARKitで作ってみました。

名刺をカメラで読み取ると、Facebookボタン、Twitterボタン、サムネイルと名前が立体的に現れて、

business_card1.gif

ボタンを押すと実際にWebViewで遷移するというものです。

business_card2.gif

今回はこのシンプルなAR名刺の作り方を紹介したいと思います。

サンプルは https://github.com/kboy-silvergym/ARKit-Emperor にありますので、コードだけみたい方はそちらをチェック。

AR名刺の作り方

  • ボタンの3DモデルをXcodeのScene Editorにて作成
  • 名刺を画像マーカーとして登録
  • 画像マーカーを読み取ったら、ボタンやサムネイルのSCNNodeを表示
  • SCNNodeはできればアニメーションさせる
  • タップしたらアクションする

ボタンの3DモデルをXcodeのScene Editorにて作成

完成形は以下です。

ar_business_card 2.png

本記事ではXcodeのScene Editorを使った3Dモデルの作り方は割愛します。先日私が書いた記事「SceneKitでプリミティブなジオメトリから3Dモデルを作ろう」のやり方と同じ要領で作ることができるので、気になる方はそちらをチェックしてみてください。

気をつけることは、あとから画像を貼ったり、タップアクションを加えたりする要素に対して名前をしっかりつけることです。

ar_business_card2 2.png

今回は、

  • twitterボタン..twitter
  • facebookボタン..facebook
  • サムネイル貼る板..thumbnail

のように名前をつけました。

名刺を画像マーカーとして登録

Assets.scassetsのARResources(なければ+ボタンから作ります)に、名刺画像をドラッグアンドドロップしましょう。

以下の画像を見るとわかるように、⚠️(注意)マークが付いています。Graffityの名刺は模様が不十分ではないため、ARマーカーとしては適切では無いようです。一応これでも行けるので、今回はこのまま進みます。

ar_business_card3 2.png

先日書いたARKit画像マーカーに適した画像適さない画像という記事で、どのような画像が適しているか、書いたのでチェックしてみてください。

画像マーカーを読み取ったら、ボタンやサムネイルのSCNNodeを表示

まずは、Configuration。

ARWorldTrackingConfigurationもしくは、ARImageTrackingConfigurationを使います。平面認識などもしたい場合は前者、画像認識しかしない場合は後者を使いましょう。

この違いについては堤さんの記事、ARKit 2.0の画像トラッキングとARKit 1.5の画像検出の違いをチェック!

今回は、ARImageTrackingConfigurationを例に解説します。

以下のコードをviewWillAppear等で実行します。先ほどセットしたマーカー画像をARReferenceImageを呼び出してセットしています。

BusinessCardViewController.swift
let configuration = ARImageTrackingConfiguration()
        
let images = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil)
configuration.trackingImages = images! // ARReferenceImageがあれば落ちないはず
configuration.maximumNumberOfTrackedImages = 1
sceneView.session.run(configuration)

sceneViewにはsceneView.delegate = selfというかんじで、ARSCNViewDelegateに準拠させ、imageAnchorが読み取られたら発火するように実装します。

BusinessCardViewController.swift
extension BusinessCardViewController: ARSCNViewDelegate {
    func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
        guard let imageAnchor = anchor as? ARImageAnchor else {
            return nil
        }
        // Do something
    }
}

画像マーカーを読み取ったら、ボタンやサムネイルのSCNNodeを表示

引き続きrenderer(:anchor)メソッドの中で、名前を判別して、それに応じてbuttonNodeを表示するというコードを書いていきます。

以下は、aと登録した名刺画像だったら、buttonNodeを表示しています。

BusinessCardViewController.swift
extension BusinessCardViewController: ARSCNViewDelegate {
    
    func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
        guard let imageAnchor = anchor as? ARImageAnchor else {
            return nil
        }
        
        switch imageAnchor.referenceImage.name {
        case "a" :
            DispatchQueue.main.async {
                self.feedback.impactOccurred()
            }
            buttonNode.scale = SCNVector3(0.1, 0.1, 0.1)
            let scale1 = SCNAction.scale(to: 1.5, duration: 0.2)
            let scale2 = SCNAction.scale(to: 1, duration: 0.1)
            scale2.timingMode = .easeOut
            let group = SCNAction.sequence([scale1, scale2])
            buttonNode.runAction(group)
            
            return buttonNode
        case "b" :
            return nil
        default:
            return nil
        }
    }
}

SCNNodeはできればアニメーションさせる

buttonNodeを表示する部分のコードについて深掘りします。以下のコードにより、

  • 一旦0.1倍に小さくする
  • 1.5倍まででかくして
  • 1倍まで戻す

というアニメーションを行なっています。

BusinessCardViewController.swift
buttonNode.scale = SCNVector3(0.1, 0.1, 0.1)
let scale1 = SCNAction.scale(to: 1.5, duration: 0.2)
let scale2 = SCNAction.scale(to: 1, duration: 0.1)
scale2.timingMode = .easeOut

let group = SCNAction.sequence([scale1, scale2])
buttonNode.runAction(group)

アニメーションの完成イメージは以下

business_card1.gif

アニメーションについてはSceneKitのアニメーションサンプル集もチェックしてみてください!

タップしたらアクションする

最後に、TwitterボタンやFacebookボタンをタップしたらWebViewに表示する部分を実装します。

画面をタッチしたら呼ばれるtouchesBeganを使って以下のように実装してみました。

  • let location = touches.first?.location(in: sceneView) でタップしたロケーションを取得
  • hitTestで、そこにNodeがあるかどうかを判別
  • Nodeがあったら名前を確認し、facebookだったらwebViewでfacebookページを表示

といった順序になっています。

BusinessCardViewController.swift
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let location = touches.first?.location(in: sceneView),
        let result = sceneView.hitTest(location, options: nil).first else {
            return
    }
    let node = result.node
    
    if node.name == "facebook" {
        let safariVC = SFSafariViewController(url: URL(string: "https://www.facebook.com/kei.fujikawa1")!)
        self.present(safariVC, animated: true, completion: nil)
    } else if node.name == "twitter" {
        let safariVC = SFSafariViewController(url: URL(string: "https://twitter.com/kboy_silvergym")!)
        self.present(safariVC, animated: true, completion: nil)
    }
}

完成イメージは以下。

business_card2.gif

まとめ

AR名刺を作る順序は以下。

  • ボタンの3DモデルをXcodeのScene Editorにて作成
  • 名刺を画像マーカーとして登録
  • 画像マーカーを読み取ったら、ボタンやサムネイルのSCNNodeを表示
  • SCNNodeはできればアニメーションさせる
  • タップしたらアクションする

大変なのは、3Dモデルを用意する部分で、それ以外は簡単だと思います。未来の名刺が楽しみですね!

サンプルコード

https://github.com/kboy-silvergym/ARKit-Emperor のBusinessCardにあります。

122
97
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
122
97

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?