見出し画像

iCade x Unity

UnityでVRアプリを作っています。たいていは Oculus Questで動かすのですが、今回はスマホ用。iPhone と Android に入れて、VR用ゴーグルに入れて使います。その際に操作はどうしようか、というわけで、Bluetoothコントローラを試してみることにして、入手したのが上の写真のエレコムJC-VRR01。

iOSでもAndroidでも使えそうなので試しに買ってみました。このコントローラは、スイッチで iOS用とAndroid用を切り替えられて、しかもそれぞれに対して「リモコンモード」と「ゲームパッドモード」を切り替えられるので、4通りの動作モードがあります。

Android編

まずはAndroidから。参考にしたのはこちらの記事。

Unityでは、Project Settings > Input Manager にて、入力に名前をつけることができ、C#のスクリプトではこの名前で参照します。そして、この記事の後半に書かれている方法で、コントローラの各ボタンが発するキーコードを調べることができます。私のエレコムコントローラについてもこの方法で調べることができました。

エレコム BluetoothコントローラJC-VRR01BKのボタンコード (Android ゲームパッドモード)

- [A]: joystick button 0
- [B]: joystick button 1
- [X]: joystick button 2
- [Y]: joystick button 3
- [volume+]: joystick button 4
- [volume-]: joystick button 5
- [select]: joystick button 8
- [start]: joystick button 9
- [click]: 不明
- [back]: 不明

トリガー形式のボタンである[click]と[back]については値が返ってきませんでした。

これを使ってUnityアプリを設定し、AndroidでビルドしてAndroidスマホに入れてみたところ、確かに意図通りに動かすことができました。簡単!

iOS編

さて、次はiOSですが、これまでの経験から言って、たいていiOSの方が何かと苦戦するので、今回もiOSは後回しにしていました。笑

まずは、上記のAndroid用に実装したアプリを何も考えずそのままiOSビルドして試してみたら、予想通りまったく反応せず。笑

そこで改めてコントローラの説明書きにヒントを探したところ、

画像1

「本製品はApple社のMFi準拠ゲームパッドではありません。iOSでのゲームパッドモードはiCade互換の信号が出力されます。」だそうです。MFi?iCade? iPhoneゲームをやってる人には当たり前の知識なのでしょうが、どうやら2種類のプロトコルがあるようです。調べてみると、MFiはAppleが正式にゲームパッドとしてサポート・認証しているもので、対応している市販アプリも多く、iCadeはそうではないみたい。暗雲が立ち込めてきました。

どうやらiCadeはキーボードを模したコードを発するらしいので、Unityで押されたキーをリアルタイムに表示する簡易的なアプリを作って、

画像2

試してみたのですが、エレコムコントローラでは反応せず。

仕方がないのでネットで iCade を検索してみたところ、こちらの githubに行き当たりました。

文字通り Unity iOS用ビルドでiCadeを使えるようにする実装です。バンザイ。さっそくダウンロードし、Readmeに書かれているとおりにやってみました。

1. アプリのスクリプトでは、普通のキー入力のようにInput.GetKeyDown() / Input.GetKeyUp() / Input.GetKey() で入力を拾うように実装する。
2. 1回ビルドする。→Xcodeでコンパイルする用のファイル群が生成される。
3. そのファイル群の中の「Classes」フォルダに、上記githubにある「iCade」で始まるファイル名のソースファイル(5個)をコピーする。
4. AppController.mmファイルの中に、上記githubにあるAppController.mmの中身をコピペ(追加)する。

というわけですが、私のUnity(2019)ではAppController.mmファイルが無くて、代わりにUnityAppController.mmファイルがあったので、そちらにコピペしました。githubの投稿日は2013年なので、それからUnityが変わったのですね。

しかし、この方法ではビルドできません。Xcodeが

'release' is unavailable: not available in automatic reference counting mode
ARC forbids explicit message send of 'autorelease'

というようなエラーを出してしまいます。

結論を言いますと、以下のようにすればOKです。

まず、「iCade」で始まるファイル名のソースファイル(5個)は、直接「Classes」フォルダにコピーするのではなく、Assets/Plugins/iOS/ フォルダにコピーします。(このフォルダが無ければ作ってください。)
そうすれば、Unityがビルド時にXcode用ファイル群に自動的にコピーしてくれますし、自分でUnityAppController.mmファイルを編集する必要がありません。

その上で、Unityの開発画面で iCadeReaderView.m と iCadeUnityLink.mm について、下図のように Compile Flags に"-fno-objc-arc"を設定します。これによって、「これらのファイルにはARCを使用しないよ」とXcodeに知らせます。

画像3

以上で、無事 iOSもビルドすることができ、iPod touchにインストールしてエレコムのコントローラをBluetooth接続してボタンを押してコードを調べることができました!

その結果、不思議なことに、各ボタンに2つのキーコードが割り当てられていて、ボタンを押したときに片方のコードが、離したときにもう片方のコードが GetKeyDown() で検出されました。

- [A]: 押し下げ時に "H", 離したときに "R"
- [B]: 同様に、U, F
- [X]: Y, T
- [Y]: J, N
- [volume+]: K, P
- [volume-]: I, M
- [select]: L, V
- [start]: O, G
- [click] [back]: 不明
- stick up: W, E
- stick down: X, Z
- stick right: D, C
- stick left: A, Q

しかも、押しっぱなしにしている状態を GetKey() で検出しようとすると、押し下げてから1秒間くらいしか検出されないことが分かりました。なんと、これは不便です。エレコムコントローラはAndroidモードではそんなことはなかったので、これはコントローラの仕様ではなく iCadeの仕様なのでしょうかね。うーむ。やっぱりMFiに行こうかな。

この記事が気に入ったらサポートをしてみませんか?