おもちゃラボ

Unityで遊びを作ってます

【Unity】ARKitで作るARモグラ叩き その1

これからUnityとARKitを使ってARもぐら叩きの作り方を紹介していこうと思います。全3回の予定です。Unityの操作になれていたら、ARKitを知らなくても1
記事あたり20分程度で試せると思います。

完成したARもぐら叩きはこんな感じになります。

f:id:nn_hokuson:20181025200107g:plain:w450

この記事はUnityを使ってARKitの使い方を解説していますが、
SwiftでARKitを学ぶには拙書「ARKit超入門」がオススメです。
コチラもチェックしていただければ嬉しいです!

今回と次回以降の記事はこちらです。

  • ARKitで作るARモグラ叩き その1
  • ARKitで作るARモグラ叩き その2
  • ARKitで作るARモグラ叩き その3

    今回の記事で作るもの

    今回はタップしたところにARで穴が3つ出現するところまで作りたいと思います。

    f:id:nn_hokuson:20181025200359j:plain:w450

    ARで穴を出現させるの流れは次の通りです。

    UnityでARKitを使う準備

    UnityでARKitを使うためにはARKit Pluginが必要になります。次のURLからダウンロードしてください。

    https://bitbucket.org/Unity-Technologies/unity-arkit-plugin/get/arkit2.0_beta.zip

    ダウンロードできたらAssets/UnityARKitPlugin/Examples/UnityARKitSceneを開きます。このシーンが一番シンプルなARKitのシーンになります。これを拡張して作っていきましょう。

    f:id:nn_hokuson:20181022192348p:plain:w300

    まずはヒエラルキーウインドウから今回作るARモグラ叩きでは不要なオブジェクトを削除します。次のオブジェクトを削除してください。

    • RandomCube
    • HitCubeParent
    • GeneratePlanes
    • ARKitControl
    • AR3DOFCameraManager

    ヒエラルキーウインドウが次のようになればOKです。

    f:id:nn_hokuson:20181022192422p:plain:w300

    続いて、ARモグラ叩き必要になるAssetをインポートします。次のURLからアセットをダウンロードしてインポートしてください。モグラ叩きの穴とモグラのアセットが含まれています。

    https://app.box.com/s/oycszpquu6ggb8pge4a10oxkrjldjkf3

    f:id:nn_hokuson:20181022192445p:plain:w600

    ちなみに・・・Unity Asset Storeでモグラ叩きのフルバージョンのアセットを販売しています。こちらも是非(^^;)


    モグラが出現する穴を作る

    ではまずはモグラが出現する穴を作っていきます。

    穴を配置する

    プロジェクトウインドウからシーンビューに「hole」をドラッグして、そこにholetexをアタッチしてください。

    f:id:nn_hokuson:20181022194732j:plain:w530

    モデルのテカリが気になる方は「hole」を選択した状態で、インスペクタに表示されるシェーダのSmoothnessを「0」に設定してください。

    f:id:nn_hokuson:20181022192906p:plain:w300

    Tagを設定する

    穴はモグラを出現させる目印にするため、Tagの設定を行っておきます。
    「hole」を選択して、インスペクタのTagから「Add Tag」をクリックしてください。

    f:id:nn_hokuson:20181022192917p:plain:w350

    「+ボタン」を押して「Hole」という名前でTagを作成してください。

    f:id:nn_hokuson:20181022192946p:plain:w350

    作成できたら、インスペクタに戻ってTagを「Hole」に変更します。

    f:id:nn_hokuson:20181022193020p:plain:w350

    穴のPrefabを作る

    今作成した穴のPrefabを作りましょう。ヒエラルキーウインドウからプロジェクトウィンドウにholeをドラッグ&ドロップしてください。Prefabの名前はholePrefabに変更しておきます。

    f:id:nn_hokuson:20181022193218j:plain

    Prefabができたら、2つほど穴を増やしておきましょう。プロジェクトウィンドウからholePrefabをドラッグ&ドロップしてください。

    f:id:nn_hokuson:20181022193236p:plain:w450

    今作成した3つの穴を一つのオブジェクトにまとめます。ヒエラルキーウインドウで「Create」→「Create Empty」を選択して空のオブジェクトを作ります。名前は「Holes」に変更しました。
    ここに先ほどの穴のオブジェクトをドラッグして子要素にしてください。

    f:id:nn_hokuson:20181022193247p:plain:w300

    最後にこの「Holes」オブジェクトもPrefabにしておきます。ヒエラルキーウインドウからプロジェクトウィンドウにドラッグ&ドロップしてください。

    f:id:nn_hokuson:20181022193349j:plain

    穴をタップで配置する

    アプリを実行したとき、画面をタップした場所にARで穴を表示するようにしましょう。

    まずはHolePlacerという名前でC#のスクリプトを作り(プロジェクトウィンドウで右クリックしてCreate→C# Script)、次のプログラムを入力してください。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.XR.iOS;
    
    public class HolePlacer : MonoBehaviour
    {
        bool isGenerated = false;
        public GameObject holesPrefab;
    
        void HitTest(ARPoint point)
        {
            List<ARHitTestResult> hitResults = UnityARSessionNativeInterface
                .GetARSessionNativeInterface()
                .HitTest(point, ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent);
    
            // 平面とあたっていた場合
            if (hitResults.Count > 0)
            {
                GameObject holes = Instantiate(holesPrefab);
                holes.transform.position = UnityARMatrixOps.GetPosition(hitResults[0].worldTransform);
                holes.transform.rotation = UnityARMatrixOps.GetRotation(hitResults[0].worldTransform);
    
                this.isGenerated = true;
            }            
        }
    
        // Update is called once per frame
        void Update()
        {
            if (!isGenerated && Input.touchCount > 0 )
            {
                var touch = Input.GetTouch(0);
                if (touch.phase == TouchPhase.Began)
                {
                    var screenPosition = Camera.main.ScreenToViewportPoint(touch.position);
                    ARPoint point = new ARPoint
                    {
                        x = screenPosition.x,
                        y = screenPosition.y
                    };
    
                    // 平面との当たり判定
                    HitTest(point);
                }
            }
        }
    }
    

    タップした場所にARのオブジェクトを表示するプログラムです。プログラムの詳しい内容は↓の記事でも解説しているので参考にしてください。

    nn-hokuson.hatenablog.com

    簡単に説明すると、ScreenToViewportPointでタップした座標をスクリーン座標に変換し、ARKitのHitTestメソッドを使って平面との当たり判定を行っています。平面と当たっていた場合にはそこに穴のオブジェクトを作成しています。また、穴を生成したあとは再度生成しないように、isGenerated変数で制御しています。

    作成したスクリプトをゲームオブジェクトにアタッチしましょう。ヒエラルキーウインドウで新たに空のゲームオブジェクト(Create→Create Empty)を生成し、Gameという名前に変更します。

    f:id:nn_hokuson:20181022193400p:plain:w300

    作成したGameオブジェクトにHolePlaceスクリプトをドラッグ&ドロップでアタッチします。

    f:id:nn_hokuson:20181022193521j:plain

    最後にHolePlacerスクリプトの「Hole Prefab」の欄に「Holes」オブジェクトをドラッグします。これにより、Holesプレハブの実態がスクリプト中のHolePrefab変数に代入されます。

    f:id:nn_hokuson:20181022193721j:plain

    実行してみる

    ココまで出来たら、実機に転送して実行してみましょう。
    「File」→「BUild Settings」を選択してBuild Settingsウインドウを開き、Scenes In BuildでUnityARKitSceneが選択されていることを確認してください。

    また、PlatformをiOSに変更していない場合は、iOSを選択してから「Switch Platform」をクリックして変更しておきましょう。

    f:id:nn_hokuson:20181022193945j:plain:w450

    「Build And Run」ボタンをクリックして実機に転送してください。画面をタッチしたら、そこに穴が表示されれば成功です!

    次回はARでモグラを表示して、穴から頭を出すようにします!お楽しみに!
    nn-hokuson.hatenablog.com

    f:id:nn_hokuson:20181025201438j:plain:w350

    参考書

    ARKitの使い方をSwiftで学びたい方はコチラがおすすめです!
    booth.pm

    Unityの基本的な使い方からC#の文法、ゲームの作り方まで解説しています!