AR名刺だけじゃない!AR実装例とARKitのサンプルの使い方について。


【前半】ARの実装例

AR といえば、Ingress(2012)やポケモンGo(2016)が有名ですが、他にもARが実装されていたりします。しかし、ARはVRに比べると特に意識することなく使っていたりするのであまり気がついていないかもしれません。

【前半】では、Ingress(2012)とポケモンGo(2016)を除いて、私がいいなと思った6つの実装例を紹介していきます。

【後半】では Unity ARKit Plugin (サンプル)について解説します。

1.セカイカメラ(2009)

頓智ドット株式会社(トンチドット)が提供していた国産のARアプリです。2009年だったのはあまりにも早すぎる!十年も前にARアプリ作った人がいるんですね。

2. 爽快!ももクロ フタの上ツアー(2013)

ロッテアイス 「爽」とモモクロがコラボした商品で、フタの上にももクロちゃんたちが登場するというものです。2013年なので、もう6年も前になります。当時、体験した私はこれがARという技術であることに全く気がついていませんでした。
https://www.itmedia.co.jp/mobile/articles/1307/18/news032.html

ここから少し時間が空きます。(私の電波が立っていなかったのか、ARアプリが作られていなかったのかは不明)

3. Flightrader24(2017)

Flightrader24 のスマートフォンアプリでは、AR機能がついています。いま、どこを飛行機が飛んでいるかを見ることができます。緯度経度に加えて、高度や速度も表示されます。大変優れものです、私はこれが大好きです。

4. ほぼ日アースボール(2018)

「アースボール」公式HP
https://earthball.1101.com/

専用のアプリをダウンロードしたスマートフォンでビニール製の地球儀を捉えると、その国の情報を表示してくれたり、地形を3D表示してくれたりといった地球儀です。

5. ホームズ かざして検索(2018)

街を歩いてて、この物件いいなと思ったらホームズのアプリでカメラをかざせば、空き物件があるかどうかを確認できます。

6. ARの名刺(2018)

自分でAR名刺アプリを作ってみたい方は、以下も読んでみてください。

【後半】Unity ARKit Plugin を使ってみよう。

1. ダウンロード

以前はUnity Asset Storeからダウンロードできたのですが、いまは以下のサイトからダウンロードしてUnityにファイルをImportするようになっています。

2. ファイルをインポート

解凍したファイルをProjectへ移動(?!)

ARKit 1.5 のサンプル
ARKit 2.0 のサンプル

の2つのタイプがあります。

「画像を認識して、それに応じて何かしらのアクションを取る」を行うために、今回使用したいサンプルは、ARKit 1.5 のサンプルの中にあります。
UnityARImageAnchor

Unityのロゴを認識して、アクションを起こすというARのSampleになっています。
このReferenceImagesの中に、自分の認識させたい画像を入れればよいということです。

3.サンプルコードの解読

上の写真にあるGenerateImageAnchor.csの中身を解読して行きましょう。

GenerateImageAnchor.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.iOS;//iOSデバイスのカメラの映像をCommandBuffer経由でUnity内のCameraに描画するクラス

public class GenerateImageAnchor : MonoBehaviour {


    [SerializeField]
    private ARReferenceImage referenceImage;

    [SerializeField]
    private GameObject prefabToGenerate;

    private GameObject imageAnchorGO;

     // Use this for initialization
    void Start () {
//それぞれの状況に合わせたメソッドの登録。
//1.対象の画像を検知したとき → AddImageAnchorを実行する。
//(そのために、このEventへAddImageAnchorメソッドを登録する。)
//UnityARSessionNativeInterface.csというスクリプトファイルの中の、ARImageAnchorAddedEventというEventのことを指しています。
        UnityARSessionNativeInterface.ARImageAnchorAddedEvent += AddImageAnchor;
//2.対象の画像が動いたりとき → UpdateImageAnchorを実行して、画像の情報を取得し直す。
//(そのために、このEventへUpdateImageAnchorメソッドを登録する。)
        UnityARSessionNativeInterface.ARImageAnchorUpdatedEvent += UpdateImageAnchor;
//3.画像を検知できなくなったとき → RemoveImageAnchorを実行する。
//(そのために、このEventへRemoveImageAnchorメソッドを登録する。)
        UnityARSessionNativeInterface.ARImageAnchorRemovedEvent += RemoveImageAnchor;

    }

    void AddImageAnchor(ARImageAnchor arImageAnchor)
    {
        Debug.LogFormat("image anchor added[{0}] : tracked => {1}", arImageAnchor.identifier, arImageAnchor.isTracked);
//カメラに写り込んだ画像と登録していた画像が一緒のとき
        if (arImageAnchor.referenceImageName == referenceImage.imageName) {
            //Positionの情報を取ってくる。
            Vector3 position = UnityARMatrixOps.GetPosition (arImageAnchor.transform);
            //Rotationの情報を取ってくる。
            Quaternion rotation = UnityARMatrixOps.GetRotation (arImageAnchor.transform);
           //imageAnchorGOというObjectを生成する。
            imageAnchorGO = Instantiate<GameObject> (prefabToGenerate, position, rotation);
        }
    }

    void UpdateImageAnchor(ARImageAnchor arImageAnchor) //ARImageAnchor型のarImageAnchor(正しい?)
    {
        Debug.LogFormat("image anchor updated[{0}] : tracked => {1}", arImageAnchor.identifier, arImageAnchor.isTracked);
        if (arImageAnchor.referenceImageName == referenceImage.imageName) {
            //画像がtrackingされている場合
            if (arImageAnchor.isTracked)
            {
                if (!imageAnchorGO.activeSelf)
                {
                    //先程生成したimageAnchorGOというObjectをtrueにsetし、表示。
                    imageAnchorGO.SetActive(true);
                }
                //Positionの情報を取ってくる。
                imageAnchorGO.transform.position = UnityARMatrixOps.GetPosition(arImageAnchor.transform); 
                //Rotationの情報を取ってくる。
                imageAnchorGO.transform.rotation = UnityARMatrixOps.GetRotation(arImageAnchor.transform);
            }
            //画像がtrackingされていない場合
            else if (imageAnchorGO.activeSelf)
            {
            //先程生成したimageAnchorGOというObjectをfalseにsetし、非表示。
                imageAnchorGO.SetActive(false);
            }
        }

    }

    void RemoveImageAnchor(ARImageAnchor arImageAnchor) //ARImageAnchor型のarImageAnchor(正しい?)
    {
//LogFormat (Object context(メッセージが適用されるオブジェクト), string format(フォーマット文字列), params object[] args(フォーマットで使用する値));
        Debug.LogFormat("image anchor removed[{0}] : tracked => {1}", arImageAnchor.identifier, arImageAnchor.isTracked);
        if (imageAnchorGO) {
            GameObject.Destroy (imageAnchorGO);
        }

    }

    void OnDestroy()
    {
        //各Eventに対して、メソッドの登録を解除。
        UnityARSessionNativeInterface.ARImageAnchorAddedEvent -= AddImageAnchor;
        UnityARSessionNativeInterface.ARImageAnchorUpdatedEvent -= UpdateImageAnchor;
        UnityARSessionNativeInterface.ARImageAnchorRemovedEvent -= RemoveImageAnchor;

    }

    // Update is called once per frame
    void Update () {

    }
}


startメソッドの中の「imageAnchorGOというObjectを生成する。」の部分の挙動を変えてあげれば、自分なりのARアプリが作れてしまうというわけです。

4. サンプルをビルド試してみる。

UnityARImageAnchor のScene(Unityのロゴのマークがついているもの)をHierarchy の枠に移動します。

その状態で、Build & Run を行います。

そして、アプリを起動してユニティーロゴをかざしてみてください。
デフォルトで入っている挙動をします。

まとめ

さらに詳しく知りたい方は、以下の本などを読んで、実装してみてください。

ARKitとUnityではじめるARアプリ開発 単行本 – 2018/3/23
薬師寺国安 (著)
https://www.amazon.co.jp/dp/4798054364