【Unity/ARFoundation】運動不足解消！ARKitでスクワットアプリ

クソアプリ Advent Calender 2020 の13日目の記事です。
前日は @onushi-k さんの [web会議に常に真顔/笑顔で参加できるアプリ](https://qiita.com/onushi-k/private/93a07c2a9a1043ec64a6) です。ycaptureすごい。
今年も素晴らしいクソアプリがたくさんある中、クソアプリをなんとか生み出せて光栄です。
知見のかたまりなのでじっくり拝見したいです。

## 前口上

2020年、コロナで大変な年でした。
テレワーク化が一気に進み、自宅での作業が増え通勤が減り、運動不足が深刻になってきました。

今回は運動不足解消とクソアプリをかけ合わせたアプリを考え、**スクワットクソアプリ**を生み出しました。
それではご覧ください。

![shit_2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100912/944192e6-03fe-6950-3774-becef21e03e9.gif)

スクワットするとプリッという音とともにうんちちゃんが落ちていきます。
（手早く作ったため作りが荒く、1回のスクワットで2回カウントされてしまっています:innocent:）

## うごくサンプル

sadakitchen/arfoundation-samples
https://github.com/sadakitchen/arfoundation-samples/tree/folk/ar_squat
（iOSのみです。一部入っていないPackageがあるので各自でDLしてください）

## 環境

- macOS Catalina 10.15.7
- Xcode 12.2 (12B45b)
- Unity 2020.1.13f1
- iPhone 11 Pro (iOS 14.2)

## 使用アセット・素材

- TextMesh Pro Version 1.2.2
フォントサイズを大きくしてもなめらかに描画してくれるのでよいです。

- DoTween Version 1.2.335
無料の定番Tweenerプラグインです。

- いらすとや うんち・便のキャラクター
https://www.irasutoya.com/2015/08/blog-post_385.html
いらすとやさん、本当にすごい。

## 参考

- Github:Unity-Technologies/arfoundation-samples  
https://github.com/Unity-Technologies/arfoundation-samples

## 制作について

今回も時間がなかったため、あり物で済ませることにしました。
前述参考のarfoundation-samplesからforkし、`HumanBodyTraking3D`シーンをベースにすることにしました。
`HumanBodyTraking3D`シーンを実行すると、人をカメラで写すことでトラッキング開始となり、ロボットがオーバーレイされ、モーションをリアルタイムでキャプチャして動きと連動させます。

スクワットのカウントの仕組みですが、ControlledRobot内のskeltonに直接編集しています。
以下のように新しいオブジェクトを追加しました。

- HipHitArea: 当たり判定用におしりに配置(Sphere Collider)
- SquatLine: 折り曲げた際、お尻と触れるべきラインを膝のボーンの子として配置(Box Collider)

![スクリーンショット 2020-12-11 23.47.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100912/b51bade4-b953-01e3-f76c-f45ab455b633.png)
※ヒットエリアがわかりやすいように着色しています

上記は SquatTrigger.cs という Trigger を管理するクラス内で接触を検知するため、Tagを`Squat`にしています。
SquatTrigger.cs はSquatLineオブジェクトにAttachしています。

```SquatTrigger.cs
using UnityEngine;

public class SquatTrigger : MonoBehaviour
{
    [SerializeField] private SquatCounterEffect squatCounterEffect;

    //OnTriggerEnter関数
    void OnTriggerEnter(Collider other)
    {
        //接触したオブジェクトのタグが"Squat"のとき
        if (other.CompareTag("Squat"))
        {
            Debug.Log("Enter");
            GetComponent<Renderer>().material.color = Color.blue;
            GameManager.instance.CountUp();
            squatCounterEffect.GenerateUnchi();
        }
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.CompareTag("Squat"))
        {
            Debug.Log("Exit");
            GetComponent<Renderer>().material.color = Color.green;
        }
    }
}
```

うんちちゃんを出すスクリプトは SquatCounterEffect.cs で、HipHitAreaオブジェクトにAttackしています。
変数 unchi にはうんちちゃんの Prefab をAttachしています。

```SquatCounterEffect.cs
using System.Collections.Generic;
using UnityEngine;

public class SquatCounterEffect : MonoBehaviour
{
    [SerializeField] private GameObject unchi;

    private List<GameObject> unchiList = new List<GameObject>();

    public void GenerateUnchi()
    {
        GameObject _unchi = Instantiate(unchi, transform.position, Quaternion.identity);
        _unchi.transform.parent = transform;
        unchiList.Add(_unchi);
    }
}
```

音はうんちちゃんの Prefab に Awake で再生されるようにしています。
（iPhoneで録音し、Auditionで調整しました。）
![スクリーンショット 2020-12-12 0.11.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100912/7bf80d5b-4c5e-63f3-89d6-ca90450008ad.png)


数値のカウントは`HumanBodyTraking3D`シーン内のCanvasに CounterText というオブジェクトを追加し、SquatCounter.cs内に表示の制御を記述しています。
実際の数値は`HumanBodyTraking3D`シーン内 GameManager オブジェクトに GameManagerシングルトンクラスをAttachして制御しています。

## まとめ

久々のUnityたのしいです(^q^)

本当はVRMを読み込んで、モデルチェンジできるようにしたかったのですが、力不足のためこのような形となりました。
あと自分から見えないのでフロントカメラに切り替えるボタンもほしいですね。
個人的な感想ですが、UnityのAR Foundation、初期と比べてかなり安定してきたと思うので、本格的なアプリも作れそうな気がします。
なにか良いアイデアがあったらトライしてみてください。

14日目は @de_teiu_tkg さんです。お楽しみに！!