めーぷるのおもちゃばこ

- アイドルになりたいエンジニア女子の制作日記 -

【Unity】AR FoundationでImage Tracking(マーカー認識)をする

ARFoundationの導入

AR Foundationでマーカー認識をする方法🐼
AR Foundationの最初の導入方法はこちらをご覧ください!
www.wwwmaplesyrup-cs6.work

ここまでできたら、以下マーカーの使用方法です。

マーカーを使用する

ヒエラルキーでAR Session Originを選択し、インスペクタでAR Tracked Image Managerコンポーネントを付けます。

f:id:maplesyrup-cs6:20191018100049p:plain
AR Tracked Image Managerを付ける


続いて、Assets下にフォルダを一つ作ります。(名前は多分なんでも大丈夫、ここではImageAssetsLibraryとします。)

f:id:maplesyrup-cs6:20191018100325p:plain
Assets下にフォルダを作る


そのフォルダの中で、右クリック>Create>XR>ReferenceImageLibraryを選択。

f:id:maplesyrup-cs6:20191018100507p:plain
ReferenceImageLibraryを追加した様子


同じフォルダ内に、マーカーにしたい画像を入れます。
マーカー画像を入れたら、ReferenceImageLibraryを選択して、インスペクタのAdd Imageからマーカーにしたい画像をセットします。
そしてSpecify Sizeにチェックを入れて、Physical Sizeを入力します。メートルなので、0.1x0.1にしました。マーカーのサイズに合わせて入力してください。
マーカーを2つや3つ登録したいときはさらにAddImageをクリックすることでマーカーを複数登録することができます。

f:id:maplesyrup-cs6:20191018105342p:plain
画像マーカーをセット


AR Session Originに付けたAR Tracked Image ManagerコンポーネントのReference Libraryに先ほどのReferenceImageLibraryをセットし、
その下のMax Number Of Moving Imagesで一度に認識したいマーカーの数を入れます。ここでは1にします。
Tracked Image Prefabのところに、マーカー認識した時に出したいオブジェクトをセットします。

f:id:maplesyrup-cs6:20191018105717p:plain
諸々設定します。


これで書き出ししてみると...
出ました!(マーカーちっちゃくて見えてないんですが後ろにあります)

f:id:maplesyrup-cs6:20191018111423j:plain
出ました!


複数マーカーを登録してみたところ、これもちゃんと出せました。

f:id:maplesyrup-cs6:20191018111505p:plain
複数も出ました
ーー

マーカーごとに出すオブジェクトを変える

Tracked Image Prefabのところにオブジェクトをセットすると、Reference Image Libraryに登録したマーカー全部に同じオブジェクトが出てしまいます。
オブジェクトごとにマーカーを出したい時もありますよね。
Tracked Image Prefabにセットしたオブジェクトを消しましょう。

ReferenceImageLibraryから使用したいマーカーを複数セットし、それぞれの名前を順番に0、1、2....としてください。
この時に、Specify Sizeの変更も忘れずに。(ここを設定し忘れているとビルド時にエラーになります。)

f:id:maplesyrup-cs6:20191112185525p:plain
マーカーをセットして名前を変更


そして、ImageRecognitionクラスを作ります。
以下のスクリプトを貼り付けてください。

using UnityEngine.XR.ARFoundation;  //これを忘れず付け足す

public class ImageRecognition : MonoBehaviour
{
        [SerializeField]
        private MarkerModelSwither _markerModelSwitcher;

        [SerializeField]
        private ARTrackedImageManager _arTrackedImageManager;

        private int _checkImageChangeNum = -1;

        private void Awake()
        {
            _arTrackedImageManager.trackedImagesChanged += OnImageChanged;
        }


        public void OnImageChanged(ARTrackedImagesChangedEventArgs args)
        {
            string _name;
            int _nameNum;

            foreach (var a in args.updated)
            {
                _name = a.referenceImage.name;
                _nameNum = int.Parse(_name);

                if (_checkImageChangeNum != _nameNum)
                {
                    Vector3 pos = a.transform.position;
                    Quaternion rot = a.transform.rotation;
                    _markerModelSwitcher.SwitchingObject(_nameNum, pos, rot);
                    _checkImageChangeNum = _nameNum;
                }
            }
        }
}


次に、MarkerModelSwitherクラスを作って、以下を貼り付けます。

public class MarkerModelSwither : MonoBehaviour
    {
        [SerializeField]
        private ARObjectManager _arObjManager;

        private int _pageNum = 0;

        private GameObject _arObj;


        public void SwitchingObject(int pageNum, Vector3 pos, Quaternion rot)
        {
            if (_arObj != null) _arObj.SetActive(false);
            this._pageNum = pageNum;
            _arObj = _arObjManager.GetArObjByNum(_pageNum);
            _arObj.SetActive(true);
            _arObj.transform.position = pos;
            _arObj.transform.rotation = rot;
            // arObj.transform.rotation = Quaternion.identity;
        }
    }


次にARObjectManagerクラスを作って、以下を貼り付けます。

public class ARObjectManager : MonoBehaviour
{
    [SerializeField]
    private GameObject[] _arObjs;

    private int _ObjNum = 0;

    private void Start()
    {
        foreach (GameObject g in _arObjs)
        {
            g.SetActive(false);
        }
    }

    public GameObject GetArObjByNum(int _pageNum)
    {
        return _arObjs[_pageNum];
    }
}


3つできたら、Unityに戻ります。
ヒエラルキーのCreateから、Create Emptyで空のゲームオブジェクトを三つ作り、先ほどのスクリプトをそれぞれにセットします。

f:id:maplesyrup-cs6:20191113103012p:plain
空のゲームオブジェクト3つ作る


それぞれのインスペクタで、
①ImageRecognitionにはMarkerModelSwitherとAR Session Originをドラッグ&ドロップでセット

f:id:maplesyrup-cs6:20191113105803p:plain
MarkerModelSwitherとAR Session Originをセット


②MarkerModelSwitherにはObjManagerをドラッグ&ドロップでセット

f:id:maplesyrup-cs6:20191113114754p:plain
ObjManagerをセット


③ObjManagerにはマーカーごとに出したいオブジェクトをセットします。最初にReferenceImageLibraryでマーカーの名前を数字にしました。
上記のスクリプトでその数字とElementの番号を対応させてあります。0番のマーカーを読み込んだら、Element0のオブジェクトを出す、といった具合です。
なので、Element0には0のマーカーにつけたいオブジェクトを、Element1には1のマーカーで出したいオブジェクトを...という感じでマーカーをセットしてください。

f:id:maplesyrup-cs6:20191113110035p:plain
オブジェクトをセット


ちなみに、この後書き出したとき筆者は「これで出るはずなのにオブジェクトが出ない!!!」と数分迷った挙句、オブジェクトがでかすぎて自分が中に入り込んでて気づかなかった、というコントを一人でしていました。
1にしていてでかすぎたので、ここではオブジェクトのサイズを0.1に設定しています。皆さんも気をつけてください。


ここまできたら大丈夫なはず。書き出しましょう!
こんな感じになるよ🐼🐼🐼マーカーごとに違うオブジェクト出せた!

f:id:maplesyrup-cs6:20191112192822g:plain
こんな感じ🐼