バランスボードとtoioを使って遊び鍛える

バランスボードが自宅に導入されたため、遊びながら鍛えるのに使えないかと思ってこんなものを作ってみました。

<iframe width="560" height="430" src="https://www.youtube.com/embed/KI-JWeGhcws" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 概要
スマホをバランスボードに貼り付け、スマホの傾きのデータを使ってtoio SDK for Unity経由でtoioを操作する仕組みです。
![balanceToiBoardSystem.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/e4177055-0ba6-0ca9-5d1f-6da88a3e8082.png)
リアルに存在するtoioを活かし、toioが動くコースを身近なものを使って自由に作ることができるのがポイントです。
今日はこのくらいやってみようとか、ゴール時間やバランススコアを見て前の日よりどのくらい改善したか、などといった遊び鍛えができるようになってます。

コンテンツ名は` BALANCE toiBoARD` という名称にしました。
バランスボードとtoioを組み合わせた造語で、小文字だけ見ると`toio`という文字が見えてくるようにしてます。
動画に映ってないですが、アプリのタイトルロゴはこんな感じ。
![app_title.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/5507f262-d48b-c6bd-430c-e1184d167d42.png)

# Standard IDの読み取り

トイオ・コレクションに付属するStandard ID付のシールを読み取って、ゴールしたりモードを変更したりできます。

toioが読み取れるStandard IDは以下の公式情報にまとまってます。
https://toio.github.io/toio-spec/docs/hardware_standard_id/

今回は以下のような使い方をしました。
![standardid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/78e39037-55f9-5cc5-eadd-018cefe830bb.png)

本当はクラフトファイターで使ってる必殺技カードを読み取りたかったけど、toioがカードの厚みを乗り越えられないことが発覚。
ペラペラのハプニングシールなら問題なかったので、ハプニングシールの読み取りに変更しました。
![card.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/866f3542-b579-f304-758c-6a1c996579ab.png)

# Unityでやっていること
スマホの傾きでtoioを操作してますが、バランスボードに貼り付けている都合上ぶるぶる揺れるので、toioが暴れてしまわないように加速度データを丸めてから使っています。
厳密なデータ処理は不要だったので、シンプルにCoroutine使ってVector3.Slerp()で丸めました。

```C#:スマホの傾きセンシング部分抜粋
public Vector3 rawAccelData = Vector3.zero;
public Vector3 accelData = Vector3.zero;

public Start()
{
    StartCoroutine(UpdateAccelCoroutine());
}

IEnumerator UpdateAccelCoroutine()
{
    while (Application.isPlaying)
    {
        rawAccelData = Input.acceleration;
        accelData = Vector3.Slerp(accelData, nowAccelData, 0.1f);
        yield return new WaitForSeconds(1f / 60);
    }
}

```
↑で丸めた方のaccelDataのx,yの値を使って、バランスボードの傾きが視覚的にもわかるようにUnityのVFX Graphで作った線状のパーティクルを動かしてます。
![vfx.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/14089b2f-af12-3d90-6e93-4508e396a4c8.gif)
元はVFX Graphを試していた時に作ったもので、何かに流用しようと思っていたのでここで使うことにしました。
VFX Graphの中身はこんな感じになってます。
![vfxgraph_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/9853717b-0af4-d3aa-bbc8-7cbee3f280ea.png)

他、開始時のカウントダウンや、屈伸モードの画面タップ時、ゴール時にVFX Graphを活用しました。
![count.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/4ed19f33-5eb6-683c-7026-c68e33e5964c.gif)　　![tap_gaoal.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/99c8f31f-b159-a64a-5d7f-ef07f840a03b.gif)


ゴール時は、スタートからゴールまでの経過時間とバランス得点を表示しています。
![capture_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/9632f22f-30a4-8088-709d-979a3ee38a31.png)

バランス得点の算出方法は再考の余地ありなのでコードは割愛しますが、ざっくり書くと以下のようなことをしてます。

- 生の加速度データと丸めた加速度データの差分（上のコードのrawAccelDataとaccelDataの差分）を一定個数分貯め続ける
- ↑の貯めた一定個数分の差分データの変化量の増減をリアルタイム監視する（安定していると差分の変化量が少ない）
- スタートからゴールまでの↑の差分変化量の平均値を使って、トータルのバランスの善し悪しをスコア化



# おわりに
もともとは子供がバランスボードを使ってくれることを期待して作り始めたのですが、これが出来上がる前に普通に乗り遊ぶようになったので、気にせず自分用として作ることにしました。

軽い運動くらいを期待して作ってみたら思ったより足にくることがわかり、デバッグのために何度も繰り返すときに辛い思いをすることになってしまいました。
特に屈伸モードをすると足がぷるぷるします。
その分鍛えられていると信じることにします。