Help us understand the problem. What is going on with this article?

ARKitで作るAR名刺

More than 1 year has passed since last update.

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にあります。

kboy
最近は「KBOYのFlutter大学」というFlutter講座をYouTubeで作ってます。
https://www.youtube.com/channel/UCReuARgZI-BFjioA8KBpjsw
kboy_flutter_univ
KBOYのFlutter大学というYouTubeチャンネル及び、Flutter開発者の集うオンラインサロンを運営しています。
https://www.youtube.com/channel/UCReuARgZI-BFjioA8KBpjsw
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした