UnityでM5StackとのBlueTooth無線通信をする

# はじめに
以前、UIFlowというツールでM5Stackとのシリアル通信をしていましたが、そちらだとBlueToothに対応していなかったので、結局Arduinoを利用することにしました。
結構つまづく箇所があったので、記事にします。






# セットアップ
今回は、VSCodeでの開発を例として紹介します。
Arduino IDEでも問題ないんですが、**予測変換とか出てこなくて使いづらく感じた**ので、僕はVSCodeを利用します。

1. VSCodeのダウンロード: https://azure.microsoft.com/ja-jp/products/visual-studio-code
1. 日本語化
左側のテトリスの欠けたOミノみたいなアイコンクリックして、「`japanese`」と検索して、一番上のやつをインストール
インストール後にVSCodeを再起動して日本語化完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/95b5abfa-ee0a-dad1-ce30-5c6d0b89e2a9.png)

1. 次に、`Arduino`と検索して追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/75fa868b-3303-575c-b8c2-4327cefaeb42.png)


1. 同様に、「`PlatformIO`」と検索して、この芋虫みたいなやつ↓も追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/d8108c47-127b-5d7a-6483-ded3ee4f48cf.png)

1. インストール後に芋虫アイコンが追加されているので、選択して`Open`をクリック、右側にウィンドウが表示されるので、「`New Project`」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/f225131f-d923-126c-2bb2-a9cc24b84368.png)


1. プロジェクト名、使用するデバイス、ディレクトリの選択をして作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/32405ec6-d37f-1d38-8f12-04ad78aa1848.png)


1. platformio.iniファイルを次のように変更
```
[env:m5stick-c]
lib_deps=m5stack/M5StickCPlus@^0.1.0

platform = espressif32
board = m5stick-c
framework = arduino
```




# VSCodeの使い方
左下らへんのアイコン群をめちゃ使います。ここ覚えとけば使えるかも

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/5aab1c25-d018-03f1-29ba-cd80e87b24a1.png)


### 最低限知っとけばいい機能
- ✅：ビルド。
- →：アップロード。デバイスに接続されている必要がある。
- 🔌(一番右のやつ)：接続されているデバイスのシリアルポートの選択。


## シリアルモニタ
ここで、Arduino側でシリアル書き込みされたデータが表示されます。
ポートとボーレートを指定して、「`Start Monitoring`」をクリックすれば表示が開始されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/1d11eef1-9e77-01e9-c344-0ea68349f818.png)


また、先程追加したArduino IDEには、**シリアルプロッタ**という、**値をグラフ化して表示してくれる機能**があります。
個人的には、こっちの方が分かりやすいのでこちらを利用しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/3f7c327b-db12-f525-1ae3-9cf2cb9d9a56.png)








# コード
一例ですが、こんな感じのコードを利用しています。
加速度とボタン入力をシリアル通信でUnity側に渡す処理です。

```.cpp
#include <Arduino.h>
#include <M5StickCPlus.h>
#include "BluetoothSerial.h"

BluetoothSerial blueTooth;

float accX, accY, accZ;

void setup()
{
  m5.begin(); // M5初期化
  m5.Imu.Init();
  blueTooth.begin("M5Device");
}

void loop()
{
  m5.update();
  m5.Lcd.fillScreen(BLACK); // 塗りつぶし

  // パラメータ取得
  bool buttonA = m5.BtnA.isPressed();
  m5.Imu.getAccelData(&accX, &accY, &accZ);    

    //blueTooth.println(accX);

    blueTooth.printf("%.1f,%.1f,%.1f,%d\r\n", accX, accY, accZ,buttonA);

  // 表示
  m5.Lcd.setCursor(0, 30);
  m5.Lcd.printf("Acc: (%.1f,%.1f,%.1f)\n", accX, accY, accZ);

  m5.Lcd.setCursor(0, 60);
  m5.Lcd.printf("Button:%d", buttonA);

  delay(100);
}
```

## 解説
まず、これらのヘッダーファイルをインクルードします。
**注意点として、これらはPlatformIO IDEがインストールされていないと、インクルードできません。**

### インクルード
```.cpp
#include <Arduino.h>
#include <M5StickCPlus.h>
#include "BluetoothSerial.h"

BluetoothSerial blueTooth;

```

また、**BlueToothのシリアル通信を使用する場合、`BluetoothSerial`というものを使用します**


### 初期化
- m5本体
- Bluetoothの初期化
- (加速度関係の初期化)
を行います。

Bluetoothの初期化では、Bluetoothのデバイス名を指定します。
これは、**PCでBluetoothに接続するときに使用されます。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/af0b78d1-9035-1726-37da-7f5c0edda378.png)



```.cpp
void setup()
{
  m5.begin(); // M5初期化
  m5.Imu.Init();
  blueTooth.begin("M5Device");
}
```


### 更新処理
必要最低限の箇所だけ抜き出しました↓
**注意点として、`print`系のメソッドでシリアルの書き込みをするのですが、改行を使用するは`\n`ではなく`\r\n`でないとUnityがフリーズしてしまいます！！注意⚠️⚠️⚠️⚠️**
(`println()`つかえば安心っぽいですけど、いちいち1行ずつ記載するのも面倒なので、`printf()`使ってます)

```.cpp
void loop()
{
  m5.update();

  // パラメータ取得
  bool buttonA = m5.BtnA.isPressed();
  m5.Imu.getAccelData(&accX, &accY, &accZ);    

    //blueTooth.println(accX);
    blueTooth.printf("%.1f,%.1f,%.1f,%d\r\n", accX, accY, accZ,buttonA);

  delay(100);
}
```


# Unity側の処理
以前の記事の内容のと同様です
よろしければ、そちらを参照にしてください。

https://qiita.com/kiku09020/items/3fb9d5ea41905f2eff9e#unity%E5%81%B4%E3%81%A7%E3%83%87%E3%83%BC%E3%82%BF%E5%8F%97%E4%BF%A1%E3%81%99%E3%82%8B


# 実装結果
こんな感じで、デバイスの加速度とボタン入力状態の取得ができました！やったー

(ボタン入力はArduino側ではintとして表示して、Unity側でその値が0じゃないかというboolに変換してます。0と1でもいいんですけど、個人的な好みでboolにしてます)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/e27bbb22-4ff1-8aec-7f1a-478f8fc09375.png)


# さいごに
普段はPCとかスマホ向けのゲームを制作していますが、こういうマニアックなデバイスでの開発も楽しいですね～


## 参考サイト

https://msr-r.net/m5stack-bluetoothserial/

https://qiita.com/ZeniZeni/items/1d0e545259fbcd9381c8