VRC内でしっぽを触られるとジョイコンが揺れるようにしてみた!!
0.前書き
こんばんは!!
おおかぜです。
僕はよくVRCという仮想世界に行って遊んだりプログラミングをしてちょっとしたものを作ったりしています。
そしてVRCの中でしっぽを触るとジョイコンがバイブレーションするものを作ってみました。
1.初期案
はじめはAndroid Studioでスマホを振動するアプリを作り、しっぽが触られたらスマホが振動するようにしようと思っていました。
ですが…
僕の技術力が圧倒的に足りずにすぐに挫折してしまいました…
なので代わりにブラウザのAPIを使ってスマホを振動させることにしました!
試しに簡単に1秒ごとに振動するような簡単なHTMLを書き実際に動かしてみると…
圧倒的に振動の強さが弱い!!
「そこで何かスマホ以外に振動するものがないか?」
と考えたところ任天堂switchのジョイコンが思いついたのでジョイコンのスイッチを振動させることにしました。
2.構想
VRCからの送信方法
VRCにはOSCという外部と通信できる機能があります。
この機能を使ってしっぽが触られたときとしっぽから手が離れた時に送信してもらい、何らかの方法でジョイコンを振動させればよいかなと思ってました。
受信方法
UnityにはOSC Coreというアセットがあるのでそれを使ってUnityで受信してUnityを使ってジョイコンを振動させています。
ジョイコンを振動させる方法
JoyconLibというアセットを使って実装しました。
3.VRCのアバターの実装
どうやらVRC Contact Receverというものをくっつければ送信してくれるらしいのでとりあえずつけて適当にコライダーを設定してみました。
エラーなくアップロードできVRC側のparameterでも認識されていてコライダーもしっかり視認できる…
しかし、肝心のOSCがなぜか送信されないのである!!
どうしてだろう…?
原因を見つけるためにVRCの公式ドキュメントを読んでいると..
このような記述があった。
なので実際に自分のアバターにちゃんと送信してほしいことの記述があるか確かめてみた。
ちゃんとあったがもしかしたら何かが原因でjsonファイルが壊れているかもしれないので削除して再生成してみた。
すると…
動かない!!でもほかの今まで送られてこなかったOSCが送られてくるようになったので効果はあったかも?
最終的にVRCのデバッグ機能でしっぽのコライダーを監視した状態で触れると送信されました。
とりあえず送信されるようになったのでVRCのアバターの実装は終了!!
4.ジョイコンを振動さる
とりあえずGoogleで調べて上のほうに出てきたGamePad APIを使用して
ブラウザでジョイコンを振動させようと思っていました。
しかし、いい感じのサンプルが見つからない上に
VRC → OSCを受信してブラウザに送るプログラム → ブラウザ
という間に一つプログラムが介入するのが少し面倒だったので他の方法をとることにしました。
なので僕が触ったことがあるPythonかnode.jsを使って実装しようと思いました。 ですがPythonもNode.jsもいい感じのライブラリが見つかりませんでした。
結果としてVRChatterならほとんどの人が触ったことがあるUnityを使うことにしました。
幸いにも僕はUdonSharpを使ってワールドギミックを作ったことがあったのでUnityのC#もある程度書くことができました。
JoyConLibという使えそうなライブラリがあったのでそれを使って実装しました。
どうやらSetRumbleという関数を呼べば振動してくれるらしいので触られたらupdate内でSetRumbleを呼び続けて触られている間は振動させるようにしました。
//省略
[NonSerialized] public bool isTouchedR = false,isTouchedL = false;
private void Update()
{
//ジョイコンが接続されていなかったら処理を抜ける
if ( m_joycons == null || m_joycons.Count <= 0 ) 受信をreturn;
if (isTouchedR)
{
m_joyconL.SetRumble(160, 320, 2.0f, 1);
}
if (isTouchedL)
{
m_joyconR.SetRumble(160, 320, 2.0f, 1);
}
}
実際にテストしてみると振動させることができたのでジョイコンを振動させることができました。
5.OSCをUnityで受信
UnityのライブラリにOSCCoreを使って実装しました。
OscCoreのバージョンが2019だったのでUnity2019で実装しました。
試しにVRCから送られてくる/avatar/parameters/AngularYのアドレスのfloat情報を受信しDebug.Logに出力しました。
しっぽが触られているかどうかは僕の場合だと
/avatar/parameters/tailTouch
に送られてくるのでboolean Inputを付けて関数を呼び出すようにしました。
スクリプトでOSCの通知が来たらジョイコンの実装で作ったisTouchedを変えてifの中が実行されるようにします。
//省略
public void OscButtonOn_tailTouch(bool message)
{
isTouched = message;
}
これで完成です!!実際に動かしてみましょう!!
6.参考にしたサイト&リンク
VRCのドキュメント
OscCoreの解説サイト
JoyconLibの解説サイト