Unity で iOS 実機と macOS Editor で BLE を使って Daydream Controller の生データを取得する
Unity で iOS 実機と macOS の Editor で、CoreBluetooth Frameworkを使って、Bluetooth Low Energyのデバイスと通信する Assetを 作成しました。
UnityエディタとiOSで動くBluetoothのプラグイン作った#unity pic.twitter.com/EeHz0iqcmL
— ふじき (@fzkqi) September 24, 2019
リポジトリ
- Unity にはBluetooth で通信する機能がないです
- iOS で Daydream のコントローラを使いたかったので、アセットを自作しました
- Unity Editorにも対応しており、Editor で実際に接続して実装して、実機は動作確認だけという開発が可能です
サンプル
Daydreamコントローラ
- 下記の条件のcharacteristicに接続すると、コントローラの生データを取得可能です
- BLEデバイスは複数のserviceを持っており、serviceは複数のcharacteristicを持っています
- characteristicごとに決められた機能が提供されており、今回はcharacteristic uuidは同名のidが複数存在するので、notifyのusageのcharacteristicを使って生データを受け取ります
項目 | 接続する端末の条件 |
---|---|
デバイス名 | Daydream controller |
service uuid | FE55 |
characteristic usage | notify |
UnityCoreBluetoothを使う
1. スキャンの開始
- CoreBluetoothManager のシングルトンのインスタンスを取得します
- poweredOn になることを確認して、スキャンを開始します
manager = CoreBluetoothManager.Shared;
manager.OnUpdateState((string state) =>
{
Debug.Log("state: " + state);
if (state != "poweredOn") return;
manager.StartScan();
});
2. 接続したいデバイス名のデバイスを見つけたら接続する
manager.OnDiscoverPeripheral((CoreBluetoothPeripheral peripheral) =>
{
if (peripheral.name != "")
Debug.Log("discover peripheral name: " + peripheral.name);
if (peripheral.name != "Daydream controller") return;
manager.StopScan();
manager.ConnectToPeripheral(peripheral);
});
3. デバイスに接続したらサービスを探す
manager.OnConnectPeripheral((CoreBluetoothPeripheral peripheral) =>
{
Debug.Log("connected peripheral name: " + peripheral.name);
peripheral.discoverServices();
});
manager.OnDiscoverService((CoreBluetoothService service) =>
{
Debug.Log("discover service uuid: " + service.uuid);
if (service.uuid != "FE55") return;
service.discoverCharacteristics();
});
4. 対象の uuidの サービスが見つかったら characteristic を探す
manager.OnConnectPeripheral((CoreBluetoothPeripheral peripheral) =>
{
Debug.Log("connected peripheral name: " + peripheral.name);
peripheral.discoverServices();
});
manager.OnDiscoverService((CoreBluetoothService service) =>
{
Debug.Log("discover service uuid: " + service.uuid);
if (service.uuid != "FE55") return;
service.discoverCharacteristics();
});
5. usage が notify の characteristic が見つかったら通知を有効にする
- 通知を有効にすることで、daydreamコントローラから連続して生データを受け取ることが可能になります
manager.OnDiscoverCharacteristic((CoreBluetoothCharacteristic characteristic) =>
{
string uuid = characteristic.uuid;
string usage = characteristic.propertis[0];
Debug.Log("discover characteristic uuid: " + uuid + ", usage: " + usage);
if (usage != "notify") return;
characteristic.setNotifyValue(true);
});
6. characteristic から通知があったら、データを受け取る
- リアルタイムで受け取れるのですが、メインスレッド保証ではないです
- そこで、一度変数に格納して、Update関数などでUIに反映させます
manager.OnUpdateValue((CoreBluetoothCharacteristic characteristic, byte[] data) =>
{
this.value = data;
this.flag = true;
});
7. Manager の動作開始
- コールバックの設定が終わった後に、Start関数を呼ぶことで、Bluetooth機能を起動します
manager.Start();
終わりに
unityエディタとiOS実機で動くBLEのプラグインを作成しました。
動作確認のたびにiOSの実機を起動するのは手間がかかるので、エディタで開発可能になることで開発が数倍楽になった気がします。
このプラグインの構造などはこちらの記事に書いてあります。