【Unity】ねずみちゃんAR（ねずみちゃんTapでカウントアップ）

環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️Unity 2019.1.9f1
⭐️Xcode11.2
⭐️iPhone7(IOS 12.2)

UnityとARKitで、ねずみちゃんAR（ねずみちゃんTapでカウントアップ）を作る。

↓↓実際に動かした動画
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">😍Unity AR🤩<br>🌅あけおめですぅ🌅<br>🐭ねずみちゃん🐭AR📲作ってみたよぉ。<br>（ねずみちゃんTapでパーティクル表示して、カウントアップする）😊<br>チーズ🧀から、ねずみちゃんが出てくるよぉ😘<a href="https://twitter.com/hashtag/unity3d?src=hash&amp;ref_src=twsrc%5Etfw">#unity3d</a> <a href="https://twitter.com/hashtag/AR?src=hash&amp;ref_src=twsrc%5Etfw">#AR</a><a href="https://t.co/bbXMZjJcXu">https://t.co/bbXMZjJcXu</a> <a href="https://t.co/w8GaP2KR77">pic.twitter.com/w8GaP2KR77</a></p>&mdash; non (@nonnonkapibara) <a href="https://twitter.com/nonnonkapibara/status/1212756859632799744?ref_src=twsrc%5Etfw">January 2, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# 準備
まず、ねずみちゃんを表示する「チーズ」モデルをBlenderで作成。
<img width="562" alt="001.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/23599765-54ba-1ff9-7a12-70efa75a728f.png">

cheese.fbxで出力する。

AR表示する　ねずみちゃんモデルをBlenderで作成。
<img width="489" alt="002.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/a8288078-6498-a211-f706-22d805c483ac.png">

mouse.fbxで出力する

# ここからUnity
Unityを起動する。
Unity AR Kitを取り込む。


【Unity】Unity ARKit Pluginが無いのでUnity-Technologies-unity-arkit-plugin-b3de628acfac.zipを使う
https://qiita.com/nonkapibara/items/3800d4ff3c56912073df

UnityARKitPlugin - Examples - UnityARKitScene
を選ぶ
<img width="672" alt="003.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/1eb41404-0f3f-ad63-186c-198d64c6397d.png">


RandomCube
HitCubeParent
GeneratePlanes
ARKitControl
PointCloudExample
AR3DOFCameraManager
は不要なので削除する
<img width="772" alt="004.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/662af646-1013-1ec7-b408-7a2165085b84.png">


<img width="661" alt="005.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/bce3dabf-cf61-fa8d-80a3-8a29bff3208d.png">

準備で用意した、「チーズ」モデルと、ねずみちゃんモデルをUnityに取り込む
<img width="541" alt="006.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/0b072ab8-1f9f-4438-c16d-bcd6f5589742.png">

「チーズ」モデルをPrefabにして、タグを「cheese」 にする
<img width="1235" alt="007.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/37a7ff08-ab44-9be4-e856-bbd00f63c27b.png">


AR表示するチーズを配置する
<img width="911" alt="008.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/89b6cb1c-c0ef-9d21-063b-3422b20805bd.png">

たくさんのチーズを１つにまとめる。
Create Emptyを作成し、その中に、たくさん作ったチーズを入れる
<img width="377" alt="009.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/8783c11f-011c-40b8-7353-54498c4830ca.png">

<img width="1200" alt="010.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/25b17414-8d1b-5b74-ba44-595722882166.png">

まとめたチーズを、Prefabにする
<img width="1202" alt="011.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/340cb9d0-be34-d3e7-b731-3325daaaacac.png">



次に、ねずみちゃんをPrefabにする
<img width="664" alt="012.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/36cf9601-b0bc-3ead-61a7-d727640e1a93.png">

タグを「mouse」にする。
ねずみちゃんに、Colliderを設定する
<img width="539" alt="013.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/9fc179a8-aa2d-1d36-83d9-e9fde4914323.png">

<img width="538" alt="014.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/87f849a9-1bd1-4799-f5c8-e72e0a57a383.png">

<img width="957" alt="015.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/cce8e766-6028-b212-bd9e-981ae46abac0.png">


<img width="767" alt="016.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/3efb0de1-10d1-9242-16c2-9bf4cb36cc43.png">


次に、チーズの床を作る。（ねずみちゃんをDownした時に、隠れるようにする）
３D ObjectーPlanを選択する
<img width="626" alt="017.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/5d60a643-4875-d177-4d2d-83b694fd7263.png">

<img width="1179" alt="018.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/e9d19e45-4904-9cef-b5e5-fcb1d501d096.png">

チーズの床を「occlusionPlaneMaterial.mat」にする

UnityARKitPlugin - Examples - Common - Materials
「occlusionPlaneMaterial.mat」を選択する
<img width="937" alt="019.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/9bac607d-e4b5-56ee-2f21-6066ead5ebc4.png">


<img width="1288" alt="020.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/90bb4411-b4d4-5827-fa98-fa5f4f36cba0.png">

# ねずみちゃんTapでカウントアップ
Tapの数値を画面に表示する
<img width="446" alt="021.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/a2618467-85b1-a2e5-34a8-5851b8226d3f.png">


<img width="1122" alt="022.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/8762904e-6d49-81fb-fe75-1a5af06ec8d6.png">

ポイント表示する為に、設定する
<img width="1271" alt="023.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/26fad5c7-5c39-a7e0-27c8-f7a7aa149f28.png">

<img width="1264" alt="024.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/3f2c4395-8f24-52b3-bd31-4292147f2adb.png">

# ねずみちゃんTapでパーティクルを表示する
<img width="460" alt="025.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/fa7fe668-29bc-ae5d-91b6-c12efa540bc3.png">


<img width="351" alt="026.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/1fe39995-cd13-1768-190c-d533df1b7861.png">

<img width="462" alt="027.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/c2f60033-8295-1666-83d6-17ed8551eff4.png">

<img width="538" alt="028.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/3464ad9c-c49f-5cdc-5c9b-be23da04f7f5.png">

<img width="1229" alt="029.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/57db1436-7a6c-dfe7-b790-53c9c97d282c.png">

# ソースコード
Create Emptyで、Game　Objectを作り、
「floorScript」と「mouseHitScript」を配置する
<img width="1219" alt="スクリーンショット 2020-01-03 0.04.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/15e589cd-0a06-8f98-afe5-e99ade5e223e.png">

```c#:floorScript.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.iOS;

public class floorScript : MonoBehaviour
{
    bool cheeseViewed = false; // チーズモデル描画
    public GameObject cheeaseObj; // チーズ
    public GameObject mouseObj; // ネズミ

    public void CreateMouse(GameObject mouse)
    {
        foreach(Transform trans in mouse.transform)
        {
            GameObject lastLayer = trans.gameObject;
            if (lastLayer.tag == "cheese") {
                Vector3 position = lastLayer.transform.position;
                Instantiate(mouseObj, position, mouseObj.transform.rotation);
            }
        }
    }


    void HitTest(ARPoint point)
    {
        List<ARHitTestResult> hitResults = UnityARSessionNativeInterface.GetARSessionNativeInterface().HitTest(point, ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent);

        if (hitResults.Count > 0)
        {
            GameObject cheese = Instantiate(cheeaseObj);
            cheese.transform.position = UnityARMatrixOps.GetPosition(hitResults[0].worldTransform);
            cheese.transform.rotation = UnityARMatrixOps.GetRotation(hitResults[0].worldTransform);

            // ネズミを生成する
            CreateMouse(cheese);

            this.cheeseViewed = true; // チーズモデル描画済み
        }
    }

    void Update()
    {
        if ((!cheeseViewed && Input.touchCount > 0) 
            && (Input.GetTouch(0).phase == TouchPhase.Began))
        {
            var touchPosition = Camera.main.ScreenToViewportPoint(Input.GetTouch(0).position);
            ARPoint arPoint = new ARPoint
            {
                x = touchPosition.x, y = touchPosition.y
            };

            HitTest(arPoint);
        }
        
    }
}

```


```c#:mouseHitScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class mouseHitScript : MonoBehaviour
{
    int hitCount = 0;

    void Update()
    {
        // ねずみちゃんTapする
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit = new RaycastHit();
            if (Physics.Raycast(ray, out hit))
            {
                pointMode(hit);
            }
        }
    }

    void pointMode(RaycastHit hit)
    {
        // ねずみちゃんをTapしたらポイントをカウントアップする
        if (hit.transform.gameObject.CompareTag("mouse"))
        {
            hit.transform.gameObject.GetComponent<mouseScript>().HitProcess();
            hitCount++;
            GameObject.Find("Point").GetComponent<Text>().text = "Point: " + hitCount.ToString();
        }
    }
}

```

ねずみちゃんPrefabに、「mouseScript」を配置し、パーティクルをDrag＆Dropして配置する
<img width="1161" alt="スクリーンショット 2020-01-03 0.09.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/d136b6b8-2c11-a3f1-22ea-18ad4d8be48f.png">

```c#:mouseHitScript.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class mouseScript : MonoBehaviour
{
    Vector3 mouseViewPosition; // ねずみちゃん表示位置
    Vector3 mouseViewDownPosition; // ねずみちゃん下がった時の位置
    bool mouseUppedFlag = true; // ねずみちゃんUP
    float timeCount = 0;
    public GameObject effect;

    void Start()
    {
        Vector3 pos = transform.position;
        pos.y += 0.05f;
        this.mouseViewPosition = pos;

        this.mouseViewDownPosition = this.mouseViewPosition - new Vector3(0, 0.1f, 0);
        // ねずみちゃんDown
        DownUnder();
    }

    void UpAbove()
    {
        transform.position = this.mouseViewPosition;
        mouseUppedFlag = true; // ねずみちゃんUP
    }

    void DownUnder()
    {
        transform.position = this.mouseViewDownPosition;
        mouseUppedFlag = false; // ねずみちゃんDown
    }

    private void Update()
    {
        this.timeCount += Time.deltaTime;
        if (this.timeCount > 3.0f)
        {
            this.timeCount = 0;
            if (this.mouseUppedFlag) {
                DownUnder();
            } else {
                UpAbove();
            }

        }
    }

    public void HitProcess()
    {
        GameObject particleObj = Instantiate(effect, transform.position + new Vector3(0, 0.04f, 0), effect.transform.rotation);
        Destroy(particleObj, 1.0f);

        this.timeCount = 0;
        // ねずみちゃんを下に下げる
        DownUnder();
    }
}

```


完成！
<img width="448" alt="スクリーンショット 2020-01-02 23.35.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/20ce7b60-bd41-9740-2c27-08f83d0e754f.png">