VRChatがOSCに対応したので、まずはNode.jsでアバターをジャンプさせてみた

[![Image from Gyazo](https://i.gyazo.com/63ea9219eb659bd581bac3b5c2920d03.gif)](https://gyazo.com/63ea9219eb659bd581bac3b5c2920d03)

## 参考記事

- VRChat [https://hello.vrchat.com/](https://hello.vrchat.com/)
- 【VRChat】オープンベータ版で「OSC」に対応 オーディオ機器でアバターの一部操作が可能に | Mogura VR [https://www.moguravr.com/vrchat-29/](https://www.moguravr.com/vrchat-29/)
- VRChat OSC for Avatars — VRChat [https://hello.vrchat.com/blog/vrchat-osc-for-avatars](https://hello.vrchat.com/blog/vrchat-osc-for-avatars)
- VRChat OSCを使ってMIDI機器でVRCHATを操作する - Qiita [https://qiita.com/takahyon/items/ba6b011f31879c32a89f](https://qiita.com/takahyon/items/ba6b011f31879c32a89f)
- OSC Overview [https://docs.vrchat.com/v2022.1.1/docs/osc-overview](https://docs.vrchat.com/v2022.1.1/docs/osc-overview)

## OSCとは

- OpenSound Control - Wikipedia [https://ja.wikipedia.org/wiki/OpenSound_Control](https://ja.wikipedia.org/wiki/OpenSound_Control)
- UDPのSocket(ソケット)通信である(が一般的)
  - 一方通行
  - 常時接続
    - たくさんの数のメッセージのやりとりに向いている
    - 逆：ブラウザでWebページにアクセスする ([HTTP通信](https://www.web-knowledge-info.com/wp/web_basic_knowledge4/#:~:text=HTTP%E3%81%AFHyperText%20Transfer%20Protocol,%E3%81%9F%E3%82%81%E3%81%AE%E9%80%9A%E4%BF%A1%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB%E3%81%A7%E3%81%99%E3%80%82))
- UDP通信でやりとりするメッセージのルール
  - メッセージのトピックは `/(スラッシュ)` 区切り
  - トピックの後ろに `,(カンマ)` でメッセージ内容（スペースのときもある）
  - 見えないところでnullコードも入ってるっぽい
  - 例：/avatar/change,avatarId12345
  - 例：/avatar/add,aaaassss98765
- 必要な情報はIPとPort(ポート)番号
  - IPアドレス:ポート番号　例 127.0.0.1:9000

### TramontanaやZigSimもスマートフォンでOSC

以前に使ったアプリもOSCで通信できます

https://tramontana.xyz/

https://qiita.com/ono-honeycomb/items/7d960a613e3ac31047f4

https://tkyko13.github.io/p5diary/202004/27/

### VRChat公式ドキュメント内では

* TouchOSC | hexler.net https://hexler.net/touchosc
* Protokol | hexler.net https://hexler.net/protokol

つまり、OSCはいろんなところで使われていますよ

## VRChatOSCのドキュメント

- OSC Overview [https://docs.vrchat.com/v2022.1.1/docs/osc-overview](https://docs.vrchat.com/v2022.1.1/docs/osc-overview)

これを踏まえて読んでみる

`--osc=9000:127.0.0.1:9001`

メッセージは一方通行！
なので、VRChat側からは

* 9001番ポートへ送っていて
* 9000番ポートで待ち受けている

他のアプリからだと、
* 9000番ポートへ送って
* 9001番ポートで待ち受ける

127.0.0.1とlocalhostと0.0.0.0の違い - Qiita [https://qiita.com/1ain2/items/194a9372798eaef6c5ab](https://qiita.com/1ain2/items/194a9372798eaef6c5ab)

## 手順

### VRChat側

- Steamで[VRChat](https://hello.vrchat.com/)をダウンロード
- SteamのVRChatの設定、プロパティから `open-beta - Open Beta` を選択
    - Windows限定っぽい
    - 02/27現在、`ik-beta - IK-Beta` に変わってますね [![Image from Gyazo](https://i.gyazo.com/a1ba6af8ea13253a92fdab133633514a.png)](https://gyazo.com/a1ba6af8ea13253a92fdab133633514a)
- VRChatをアップデート
- デスクトップモードで起動
- VRChat内でOSCを有効化
  - デバッグメニューを出しておくといいかも
  - そこを見るとポート番号は`9000番`だということがわかります

[![Image from Gyazo](https://i.gyazo.com/c5801846927efda5a156c6718f0dae2d.png)](https://gyazo.com/c5801846927efda5a156c6718f0dae2d)

### Node.jsで通信してみる

- `npm init -y`
- `npm i node-osc`

```js
const osc = require('node-osc');

const client = new osc.Client('127.0.0.1', 9000);
let count = 0;

// 1秒間隔で0,1を交互に送る
// たぶん1がジャンプボタンを押して、0が離す動作っぽい
setInterval(() => {
  client.send('/input/Jump', count % 2);
  count++;
}, 1000);

const server = new osc.Server(9001, '0.0.0.0');
server.on('/avatar/change', (avatarId) => {
  console.log('アバターチェンジ！ '+avatarId);
});
```

[![Image from Gyazo](https://i.gyazo.com/63ea9219eb659bd581bac3b5c2920d03.gif)](https://gyazo.com/63ea9219eb659bd581bac3b5c2920d03)

[![Image from Gyazo](https://i.gyazo.com/71ec22fa7ec2a52ad53afead4edd8a9f.gif)](https://gyazo.com/71ec22fa7ec2a52ad53afead4edd8a9f)

コメントでも書いてある通り、`/input/Jump` へ送るだけだとなぜかジャンプしなくて…
値を1と0交互に送ってあげるとできました

ドキュメント内を読むと、1がボタンを押し込む動作で、0が離す動作っぽかったでした（ちょっと躓いた…）

アバターの変更イベントも来ました！

## 次回予定

M5StackCore2で通信してみる！

しかもUIFlowで！