【Unity】OscJackの使い方

UnityのOSCライブラリであるOscJackについて調べました。
[keijiro/OscJack: Lightweight implementation of OSC server/client in C\# \(Unity\)](https://github.com/keijiro/OscJack)

本記事の内容はUnityバージョン2021.2.9f1、エディタ上でのみ検証しています。

## インストール

Scoped Registryを使用してインストールします。
`/Packages/manifest.json`に以下を追記します。

```
{
  "scopedRegistries": [
    {
      "name": "Keijiro",
      "url": "https://registry.npmjs.com",
      "scopes": [ "jp.keijiro" ]
    }
  ],
  "dependencies": {
    "jp.keijiro.osc-jack": "1.0.3",
    ...
  }
}
```

`Project Settings > Package Manager`でScoped Registryを登録して、Package Managerから`OSC Jack`をインストールすることも可能です。

## 使い方

### OSCの受信

#### コンポーネントを用いたOSCの受信

`EventReceiver`コンポーネントで指定したOSCアドレスを受信したときに受信したデータを引数にメソッドを実行することができます。
`Add Component > OSC > Event Receiver`から`EventReceiver`コンポーネントを追加します。
![EventReceiver_s.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/484b4a45-4b94-dca1-1dc8-9bcfc1cb42a2.png)

#### スクリプトを用いたOSCの受信

`OscServer`を用いることでスクリプトからOSCを受信できます。
`AddCallback`でOSCアドレスとそれを処理するメソッドを紐づけます。`AddCallback`で登録するメソッドはメインスレッド外で実行されるので、ほとんどのUnity APIは使用することができません。Unity APIを使用したい場合、自分でキューイングなどの処理を実装する必要があります。

```c#:OscJackServerSample.cs
using UnityEngine;
using OscJack;

public class OscJackServerSample : MonoBehaviour
{
    [SerializeField] int port = 8000;
    OscServer server;

    void OnEnable()
    {
        server = new OscServer(port);
        server.MessageDispatcher.AddCallback(
            "/OscJack/sample",
            (string address, OscDataHandle data) => {
                var stringValue = data.GetElementAsString(0);
                var floatValue = data.GetElementAsFloat(1);
                var intValue = data.GetElementAsInt(2);
                Debug.Log($"OscJack receive: {address} {stringValue} {floatValue} {intValue}");
            }
        );
    }

    void OnDisable()
    {
        server.Dispose();
        server = null;
    }
}

```

#### OSC受信のモニタリング

`Menu > Window > OSC Monitor`で`OSC Monitor`ウィンドウを開くことができます。`OSC Monitor`を使用することでOSCの受信をモニタリングすることができます。

### OSCの送信

#### コンポーネントを用いたOSCの送信

`Property Sender`コンポーネントで指定したオブジェクトのプロパティ値をOSCで送信できます。`Add Component > OSC > Property Sender`から`Property Sender`コンポーネントを追加します。
![PropertySender_s.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/3c4487f5-75db-78da-af9d-663ab235bd5b.png)
デフォルトでは値が変化したときのみOSCを送信しますが、`Keep Sending`をオンにすると値に変化がなくてもOSCを送信します。

#### スクリプトを用いたOSCの送信

`OscClient`を用いることでスクリプトからOSCを送信できます。

```c#
using UnityEngine;
using OscJack;

public class OscJackClientSample : MonoBehaviour
{
    [SerializeField] string ipAddress = "127.0.0.1";
    [SerializeField] int port = 8080;
    OscClient client;

    void OnEnable()
    {
        client = new OscClient(ipAddress, port);
    }

    void OnDisable()
    {
        client.Dispose();
    }

    void Update()
    {
        client.Send("/OscJack/sample", 1.23f, 4.56f, 7.89f);
    }
}
```

`OscClient#Send`のオーバーロードメソッドは次のようになっているように、送信できる形式は1～4個のint、1～4個のfloatまたは1つのstringです。

```c#
public void Send(string address);
public void Send(string address, int data);
public void Send(string address, int element1, int element2);
public void Send(string address, int element1, int element2, int element3);
public void Send(string address, float data);
public void Send(string address, float element1, float element2);
public void Send(string address, float element1, float element2, float element3);
public void Send(string address, float element1, float element2, float element3, float element4);
public void Send(string address, string data);
```


## まとめ

UnityのOSCライブラリであるOscJackについて解説しました。
`EventReceiver`や`PropertySender`といったコンポーネントを使用してOSCを送受信する場合には容易に使用できます。しかし、スクリプトから使用する場合には受信時のキューイングを自分で実装しなければならなかったり、送信できる形式が限定的であったりと少し使う場面を選ぶかなというのが個人的な印象です。