toio SDK for Unityで開発用プレイマットを使う場合に移動出来ない領域が無いようにする方法

## はじめに
この記事では、toio SDK for Unityで開発用プレイマットを使う場合に移動出来ない領域があるときに行う設定について述べます。
なお、ここに記載されているのは[toio SDK for Unity][link-1](version 1.0.1)で調査した情報です。
今後登場するバージョンでは仕様が変わる可能性もあるので、ドキュメントを参照するなどしてください。

## toio™開発用プレイマットの特徴と仕様

toio SDK for Unityでは、実物同様、[toio™開発用プレイマット [TMD01SS]][link-2]を使うことが出来ます。
この開発用プレイマットは#01～#12までの12枚があり、それぞれ異なるPosition ID(マット上の絶対座標)の範囲が設定されていて、12枚を組み合わせると合わせると横1260mm x 縦1188mm のスペースでCubeを指定位置に移動させられるようになります。

マットの並べ方とPosition IDの範囲などの仕様は販売元のスイッチサイエンスさんのサイトにある[参考仕様ドキュメント（pdf）][link-3]に記載されています。

toio SDK for Unityではtoio™開発用プレイマットとマット番号を選択することが出来ます。(下記画像```Mat (Script)```の設定を参照)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39561/eb48d4a3-9179-48fb-af90-9bede53fc5bf.png)

## toio SDK for Unityで扱う際の注意点と必要な設定

Cubeをマット上のPosition IDに移動する場合、```CubeHandle```クラスの [Move2Target()][link-4] というAPIが使えるのですが、[toio SDK for Unity][link-1]のデフォルトの実装では、移動できない範囲が存在します。
この理由は、```CubeHandle```でボーダー判定(移動可能な範囲の閾値判定)をしていて、ボーダーの値が[CubeHandle.cs](https://github.com/morikatron/toio-sdk-for-unity/blob/4301ad738c236ac1fd3fb5c19b174da6d5b56008/toio-sdk-unity/Assets/toio-sdk/Scripts/Cube/CubeHandle.cs#L29)の```CenterX```、```CenterY```、```RangeX```、```RangeY```から算出されています。なおかつこれらの値はインスペクタでマットタイプやマット番号を変えても、自動では変わってくれません。

### #01～#12どれでも隅々まで移動できるようにするにはアプリ開発者が設定を変更しなければならない
toio™開発用プレイマット #01の場合はデフォルト値でも概ね問題ないのですが、それ以外のマット番号の場合はデフォルトの値のままだとボーダー判定処理の影響で移動できない領域が出て来てしまいます。
具体的には```CenterX```、```CenterY```、```RangeX```、```RangeY```を設定する必要があります。
もし#01～#12どのマットでも全域移動できるようにするしたいなら、各```CubeHandle```に対して```CenterX=492``` (=340+(644-340)/2)、```CenterY=466```(#6のYの最大値)、```RangeX=916```(=949-34+1)以上、、```RangeY=864```(=898-35+1)以上の値を設定する必要があります。
この処理の実装方法の例は[Sample_MultiMat.cs][link-mm]にもあります。
```CubeHandle```だけ使って```Navigator```を使わないのであれば、以下のように実装すればよいようです。

```TestScene.cs
    async void Start()
    {
        cubeManager = new CubeManager();
        await cubeManager.MultiConnect(1);
        foreach (CubeHandle handle in cubeManager.handles)
        {
            handle.CenterX = 492;
            handle.CenterY = 466;
            handle.RangeX = 916;
            handle.RangeY = 864;
        }
    }
```
開発用マット#4で端まで移動できている例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39561/2fdcb7c7-8df0-702e-6a78-5701d2ab08d6.png)

もし群制御などを行うために```Navigator```も使う場合には、```AddBorder()```というAPIも呼び出す必要があります。```AddBorder()```のAPI仕様は[こちら](https://github.com/morikatron/toio-sdk-for-unity/blob/4301ad738c236ac1fd3fb5c19b174da6d5b56008/docs/usage_navigator.md#addborder)にあります。
この使用例は上記と同様[Sample_MultiMat.cs][link-mm]に記載されています。

```TestScene.cs
    async void Start()
    {
        cubeManager = new CubeManager();
        await cubeManager.MultiConnect(1);
        foreach (CubeHandle handle in cubeManager.handles)
        {
            handle.CenterX = 492;
            handle.CenterY = 466;
            handle.RangeX = 916;
            handle.RangeY = 864;

            var navi = new CubeNavigator(handle);
            navi.usePred = true;
            navi.mode = Navigator.Mode.BOIDS_AVOID;
            cubeManager .navigators.Add(navi);
            navi.ClearWall();
            navi.AddBorder(35, x1:34-35, x2:949+35, y1:35-35, y2:898+35); // 34<=x<=949, 35<=y<=898を移動可能な範囲にする
        }
    }
```

### 脱輪注意
ボーダーの値を追い込み過ぎると脱輪することがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39561/f936d10d-4c0d-08d9-9813-8ce6d2d4a95d.png)

以上になります。

[link-1]:https://morikatron.com/t4u/
[link-2]:https://www.switch-science.com/catalog/6650/
[link-3]:https://d2air1d4eqhwg2.cloudfront.net/media/files/1fa512cd-858f-4f77-a3e0-241c1eb8213d.pdf
[link-4]:https://github.com/morikatron/toio-sdk-for-unity/blob/4301ad738c236ac1fd3fb5c19b174da6d5b56008/docs/usage_cubehandle.md#move2target
[link-mm]:https://github.com/morikatron/toio-sdk-for-unity/blob/4301ad738c236ac1fd3fb5c19b174da6d5b56008/toio-sdk-unity/Assets/toio-sdk/Samples/Sample_MultiMat/Sample_MultiMat.cs#L26