おもちゃラボ

Unityで遊びを作っていきます

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

前回はARのモグラが穴から出てくるところまでを作りました。最終回はモグラをタップで叩けるようにします。また、叩いたときのエフェクトも表示したり、アニメーションを追加したりします。

f:id:nn_hokuson:20181101195657j:plain

前回までの記事はこちらです。

  • ARKitで作るARモグラ叩き その1
  • ARKitで作るARモグラ叩き その2
  • ARKitで作るARモグラ叩き その3
     
    今回もUnityとARKit Pluginを使ってすすめていきます。
    拙書「ARKit超入門」もよろしくお願いします!

    モグラを叩けるようにする

    ARモグラ叩きなのでモグラをタップで叩けるようにしましょう。MoleControllerに次のHitメソッドを追加してください。

        public void Hit()
        {
            this.time = 0;
            Down();
        }
    

    ここではモグラを叩いたときに呼び出すHitメソッドを追加しました。Hitメソッドの中ではDownメソッドを呼んでいます。これにより、叩かれたら、モグラが地中に戻ります。

    次にモグラを叩く側のプログラムを作っていきますが、その前にモグラに「Mole」というタグを設定しておきます。これは叩いたオブジェクトがモグラかどうかを判別するのに使います。

    インスペクタのTagのドロップダウンを開き、Add Tagをクリックします。
    f:id:nn_hokuson:20181105231132p:plain:w300

    次に「+ボタン」をクリックして「Mole」というタグを追加します。
    f:id:nn_hokuson:20181105231211p:plain:w300

    プロジェクトウインドウでmolePrefabを選択して、Tagの欄に今作成した「Moleタグ」を設定して下さい。
    f:id:nn_hokuson:20181105231241p:plain:w300

    モグラをタッチで叩くスクリプトを作成します。プロジェクトウィンドウにHammer.csを作成して、次のスクリプトを入力してください。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Hammer : MonoBehaviour 
    {
    	void Update () 
        {
            if (Input.GetMouseButtonDown(0))
    		{
    			Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit = new RaycastHit();
                if(Physics.Raycast(ray, out hit))
                {
                    if(hit.transform.gameObject.CompareTag("Mole"))
                    {
                        hit.transform.gameObject.GetComponent<MoleController>().Hit();
                    }
                }
    		}
    	}
    }
    

    ScreenPointToRayメソッドを使って、タップしたところからRayを飛ばしています。そのRayがコライダと衝突するかをPhysics.Raycastメソッドで調べます。衝突したオブジェクトのTagを見て、モグラだった場合はMoleControllerのHitメソッドを呼び出しています。

    スクリプトが出来たら、これもGameオブジェクトドラッグ&ドロップしてアタッチしておきましょう。

    f:id:nn_hokuson:20181105231423j:plain

    これでモグラを叩いたら、叩かれたモグラが地中に戻るようになりました。実機にインストールして試してみてください。

    得点を表示する

    次にモグラを何匹叩いたのかを表示するUIを作ります。ヒエラルキーウインドウから「Create」→「UI」→「Text」を選択してください。

    ヒエラルキーウインドウにCanvasオブジェクトと、その子要素にTextが追加されます。Textの名前はScoreに名称変更します。

    f:id:nn_hokuson:20181105231505p:plain:w250

    実機の画面サイズによらずに、一定の大きさでUIが表示されるようにします。 ヒエラルキーウインドウでCanvasを選択して下さい。インスペクタからCanvas Scalerを探して、「UI Scale Mode」を「Scale With Screen Size」に設定し、「Screen Match Mode」を「Expand」に設定します。

    f:id:nn_hokuson:20181105231553p:plain:w300

    次にスコアの見た目の調節を行います。Textを画面上部に移動して、Anchorの場所をTopCenterに設定します。

    f:id:nn_hokuson:20181105231722j:plain:w600

    また、TextのfontやAlignment、Colorなど各種パラメータを設定します。今回は次のように設定しましたが、ここは好みに応じて変更して下さい。

    f:id:nn_hokuson:20181105231809p:plain:w300

    スクリプトから得点のUIを更新します。先ほど作成したHammerスクリプトを次のように修正してください。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class Hammer : MonoBehaviour 
    {
        int count = 0;
    
    	void Update () 
        {
            if (Input.GetMouseButtonDown(0))
    		{
    			Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit = new RaycastHit();
                if(Physics.Raycast(ray, out hit))
                {
                    if(hit.transform.gameObject.CompareTag("Mole"))
                    {
                        hit.transform.gameObject.GetComponent<MoleController>().Hit();
    
                        count++;
    
                        GameObject.Find("Score").GetComponent<Text>().text
                                 = "Score: " + count.ToString();
                    }
                }
    		}
    	}
    }
    

    モグラを叩いた数を数えるために、count変数を追加しています。モグラを叩いた場合はcountをインクリメントします。そのあと、Findメソッドを使ってシーンから「Score」という名前のオブジェクト(先ほど追加したText)を探して、そこにcount変数の値を表示しています。

    実行すると、叩いたモグラの数に応じてスコアが増えていくのが分かります。

    f:id:nn_hokuson:20181106191331j:plain:w480

    パーティクルを出す

    いまのままではモグラを叩いたときの反応が少し薄いです。叩いたタイミングでパーティクルを表示しましょう。今回は次のような感じの破砕エフェクトを作ります。

    f:id:nn_hokuson:20181106192102g:plain

    ヒエラルキーウインドウから「Create」→「Effect」→「Particle」を選択してください。今回は中心から円形に飛び散るようなエフェクトを作ります。

    まずは基本のパラメータを次のように設定します。
    f:id:nn_hokuson:20181105231844p:plain:w340

    パーティクルの放出形状は半球形、放出量はBurstで50に設定しました。
    f:id:nn_hokuson:20181105231909p:plain:w340

    飛び散ったパーティクルは小さくなるようにSize over Lifetimeのグラフを減衰系に設定します。
    f:id:nn_hokuson:20181105232012p:plain:w340

    最後に飛び出すパーティクルの形を立方体にするため、「Render Mode」を「Mesh」に設定し、「Mesh」は「Cube」を選択します。
    f:id:nn_hokuson:20181105232100p:plain:w340

    最後にこのパーティクルをPrefab化します。ヒエラルキーウインドウのParticle Systemをプロジェクトウィンドウにドラッグして、名前をEffectPrefabに変更して下さい。

    f:id:nn_hokuson:20181105232209j:plain:w600

    モグラを叩いたときにこのエフェクトを表示するように、MoleController.csに追記します。ここでは差分のプログラムだけ書きます。

    先頭で今作成したPrefabを格納するための変数を作ります。

        public GameObject effect;
    

    Hitメソッドの中にパーティクルを生成するプログラムを追加します。

        public void Hit()
        {
            GameObject g = Instantiate(effect, transform.position+new Vector3(0, 0.04f, 0), effect.transform.rotation);
            Destroy(g, 1.0f);
    
            this.time = 0;        
    
            Down();
        }
    

    Hitメソッドは叩かれたときに呼び出されるのでした。なので、モグラを叩いたタイミングで、その叩いたモグラの位置にパーティクルが生成されます。

    最後に、上で宣言したeffect変数にEffectPrefabの実体を代入します。プロジェクトウインドウでmolePrefabを選択して、MoleControllerのeffectの欄に「EffectPrefab」を設定します。

    f:id:nn_hokuson:20181105232454j:plain:w600

    これでモグラを叩いたときにエフェクトが表示されるようになります。

    モグラをアニメーションで動かす

    今のままではモグラが上下に瞬間移動しているので、見た目に気持ちよくありません。なめらかに移動するように修正します。UnityにはDoTweenというアニメーションのためのアセットがあるので、これを使います。

    次のURLからDoTweenをダウンロードして、プロジェクトにインポートしましょう。

    次のようなウインドウが表示されるのでSetup DoTweenをクリックして次の画面でApplyを押します(Applyボタンが押せるようになるまで時間が少しかかります)

    f:id:nn_hokuson:20181105232545j:plain:w250 f:id:nn_hokuson:20181105232558p:plain:w250

    これでセットアップは完了です。あとはモグラを動かすスクリプト(MoleController.cs)を少し修正します。DoTweenを使うためにDG.Tweeningをインポートします。

    using DG.Tweening;
    

    また、UpメソッドとDownメソッドを次のように書き換えて下さい。

    void Up()
    {
        transform.DOMoveY(groundLevel.y, 0.5f);
        this.isOnGround = true;
    }
    
    void Down()
    {
        transform.DOMoveY(undergroundLevel.y, 0.5f);
        this.isOnGround = false;
    }
    

    DoMoveYメソッドは第一引数に指定したy座標までアニメーションしながら移動します。移動時間は第二引数で指定します。これでARのモグラがなめらかに動くようになりました。

    完成

    これで無事ARモグラ叩きが完成しました。お疲れ様でした!!

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

    実際に手を動かして作ってみていかがでしたでしょうか。UnityとARKitを使えば、簡単にARのアプリケーションが作れることを体験出来たのではないかと思います。

    参考書

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

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

    Unityの教科書 Unity 2018完全対応版 2D&3Dスマートフォンゲーム入門講座 (Entertainment&IDEA)

    Unityの教科書 Unity 2018完全対応版 2D&3Dスマートフォンゲーム入門講座 (Entertainment&IDEA)

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

    前回は画面をタップしたところに穴を表示するプログラムを作りました。今回はARのモグラを生成して上下するようにするところまでを作ります。完成イメージはこんな感じです。

    f:id:nn_hokuson:20181101195113j:plain

    関連記事はこちらです。前回はタッチしたところにARで穴を表示するところまでを解説しています。

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


    今回もUnityとARKit Pluginを使ってすすめていきます。
    手前味噌ですが・・・Swiftを使ってARKitを学びたい方はこちらの書籍がオススメです


    モグラのPrefabを作る

    まずはプロジェクトウィンドウからシーンビューにmoleをドラッグします。そのmoleにmoletexをアタッチしてテクスチャを設定しましょう。

    f:id:nn_hokuson:20181031221451j:plain:w500

    今回もモグラのテカリが気になる方は、moletexマテリアルのインスペクタからSmoothnessを「0」に設定してください。

    f:id:nn_hokuson:20181031221607p:plain:w320

    次にモグラを叩いたときの判定をするために、コライダをアタッチしておきます。ヒエラルキーウインドウでmoleを選択した状態で、インスペクタの「Add Component」から「Capsule Collider」を選択してください。

    f:id:nn_hokuson:20181031221622p:plain:w500

    Capsule Colliderがモグラにフィットするようにパラメータを次のように調節してください。

    f:id:nn_hokuson:20181031221640p:plain:w320

    ここまでで、一旦モグラのPrefabを作っておきましょう。ヒエラルキーウインドウからプロジェクトウィンドウにmoleをドラッグ&ドロップしてください。ファイル名はmolePrefabに変更しておきます。

    f:id:nn_hokuson:20181031222020j:plain

    ヒエラルキーウインドウにあるモグラは「右クリック」→「Delete」で消しておきます。

    穴の場所にモグラを生成する

    今作成したモグラのPrefabを穴の位置に生成するスクリプトを作ります。

    プロジェクトウィンドウのHolePlacerスクリプトに、GenerateMolesメソッドとその呼び出し部分のプログラムを追加してください。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.XR.iOS;
    
    public class HolePlacer : MonoBehaviour
    {
        bool isGenerated = false;
        public GameObject holesPrefab;
        public GameObject molePrefab;
    
        public void GenerateMoles(GameObject holes)
        {
            foreach (Transform t in holes.transform)
            {
                GameObject child = t.gameObject;
                if(child.tag == "Hole")
                {
                    Vector3 pos = child.transform.position;
                    Instantiate(molePrefab, pos, molePrefab.transform.rotation);
                }
            }
        }
        
        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);
    
                // モグラを生成する
                GenerateMoles(holes);
                
                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);
                }
            }
        }
    }
    

    前回のプログラムにGenerateMolesメソッドを追加しています。このメソッドは引数に穴(3つの穴を子要素にもつオブジェクト)のオブジェクトを受け取ります。その子要素を調べて「Hole」というタグを持っていれば、その位置にモグラを生成しています。また、HitTestメソッドの中でこのGenerateMolesメソッドを呼び出しています。

    プログラムが追加できたら、GameオブジェクトにアタッチしたHolePlacerスクリプトのMole Prefabの欄にmolePrefabの実体をセットしてください。

    f:id:nn_hokuson:20181031222311j:plain

    ここまでで実行してみましょう。画面をタップすると穴が配置され、その上にモグラが表示されるかを確かめてください。

    f:id:nn_hokuson:20181101195727j:plain:w500

    モグラを動かす

    次にモグラが穴から出たり入ったりするようにしましょう。MoleControllerというスクリプトを作成して、次のプログラムを入力して下さい。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class MoleController : MonoBehaviour {
    
        Vector3 groundLevel;
        Vector3 undergroundLevel;
        public GameObject effect;
    
        bool isOnGround = true;
        float time = 0;
    
        void Up()
        {
            transform.position = groundLevel;
            this.isOnGround = true;
        }
    
        void Down()
        {
            transform.position = this.undergroundLevel;
            this.isOnGround = false;
        }
    
        void Start () 
        {
            this.groundLevel = transform.position;
            this.undergroundLevel = this.groundLevel - new Vector3(0, 0.2f, 0);
    
            // 地中に隠す
            Down();
    	}
    	
    	void Update () 
        {
            this.time += Time.deltaTime;
    
            if( this.time > 2.0f )
            {
                this.time = 0;
                if( this.isOnGround) 
                {
                    Down();
                }
                else 
                {
                    Up();
                }
            }
        }
    }
    

    このスクリプトでは、time変数を使って時間をカウントして、2秒ごとにモグラを上下させています。プログラムの分かりやすさを優先して、ここではアニメーションの設定はまだしていません。なのでモグラは地上と地中の間を瞬間移動します。次の記事でDOTweenを使ったアニメーションの方法を紹介します。

    作成したMoleControllerスクリプトをモグラのPrefabにドラッグ&ドロップしてアタッチします。

    f:id:nn_hokuson:20181031222631p:plain

    実機にインストールして、モグラが上下するか確認してみましょう。

    f:id:nn_hokuson:20181101200047g:plain:w500

    モグラは上下していますが、穴の下にいるモグラまで見えてしまっていますね。これはARKitが現実世界にあるものとARオブジェクトの前後関係を認識できないのが原因です。この地中のモグラが見えてしまう対策をしていきます。

    オクルージョン対策

    現実世界にあるものとの前後関係がわからない問題は、昔からARにはつきものの問題です。ARKitではカメラ映像の上にARオブジェクトを強制的にべた書きするため、このように前後関係が崩れてしまいます。

    Depthカメラを使えば、画像の奥行きがわかるため、多少の前後判別はできるようになります。ただ、現状ではリアルタイムで計算するにはコストが高く、根本的に解決されたわけではありません。

    そこでARKitを使ってオクルージョンを実現するには手動で、オクルージョン用の平面を設定する必要があります。この平面を設定することで、それよりも奥にあるオブジェクトは描画されなくなります。

    f:id:nn_hokuson:20181101202430p:plain:w550

    まずはヒエラルキーウインドウで「Create」→「3D Object」→「Plane」を選択して穴の真下に設定します。
    また、今作成した平面をHolesの子要素にしておきます。

    f:id:nn_hokuson:20181031222809j:plain:w600

    次に平面にオクルージョン用のマテリアルを設定します。UnityARKitPlugin/Common/MaterialsにあるocclusionPlaneMaterialを平面にドラッグしてください。これにより、この平面より下にあるオブジェクトは描画されないようになります。

    f:id:nn_hokuson:20181031223100j:plain:w500

    HolesPrefabにも変更を反映するため、ヒエラルキーウインドウでHolesを選んでからインスペクタの「Apply」ボタンを押してください。

    f:id:nn_hokuson:20181031223158p:plain:w320

    オクルージョンに使ったシェーダを少しだけ見ておきましょう。UnityARKitPlugin/Example/Common/Shaders/MobileOcclusion.shaderです。ポイントは次の3行です。

    ZWrite On
    ZTest LEqual
    ColorMask 0
    

    ZWriteをOnにしてデプステストは行いつつ、ColorMaskに0を設定することで描画は行わないようにしています。つまりデプステスト的にはそこにオブジェクトがあるけど、見た目にはなにもないというおばけ状態ですね(笑)
     
     
    f:id:nn_hokuson:20181101202845p:plain:w600
     
    これにより背後のオブジェクトがデプステストにかかって描画されなくなります。シェーダについては次の記事を参照下さい。

    nn-hokuson.hatenablog.com

    実行してみる

    オクルージョン用の平面を使用したことで、穴の下にいるモグラは描画されなくなりました。

    f:id:nn_hokuson:20181101200103g:plain:w500

    今回はココまでにしましょう。次回は最終回です。最後の仕上げにモグラのアニメーションとパーティクルの発生、GUIの設定などをしていきますよ!

    nn-hokuson.hatenablog.com

    参考書

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

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

    Unityの教科書 Unity 2018完全対応版 2D&3Dスマートフォンゲーム入門講座 (Entertainment&IDEA)

    Unityの教科書 Unity 2018完全対応版 2D&3Dスマートフォンゲーム入門講座 (Entertainment&IDEA)

  • 【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#の文法、ゲームの作り方まで解説しています!

    Unityの教科書 Unity 2018完全対応版 2D&3Dスマートフォンゲーム入門講座 (Entertainment&IDEA)

    Unityの教科書 Unity 2018完全対応版 2D&3Dスマートフォンゲーム入門講座 (Entertainment&IDEA)