【Unity】extOSCの使い方

UnityのOSCライブラリであるextOSCについて調べました。
[Iam1337/extOSC: extOSC is a tool dedicated to simplify creation of applications in Unity with OSC protocol usage\.](https://github.com/Iam1337/extOSC)

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

## インストール

### Scoped Registryからインストール

`/Packages/manifest.json`に以下を追記します。

```
{
    "scopedRegistries": [
	    {
		    "name": "package.openupm.com",
		    "url": "https://package.openupm.com",
		    "scopes": [
			    "com.iam1337.extosc",
		    ]
	    }
    ],
    "dependencies": {
	    "com.iam1337.extosc": "1.19.7",
        ...
    }
}
```

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


### Git URLからインストール

Package Managerの`Add package from git URL...`で以下のURLを追加してインポートします。

```
https://github.com/iam1337/extOSC.git#upm
```

### unitypackageでインストール

[Releases](https://github.com/Iam1337/extOSC/releases)ページからunitypackageをダウンロードしてインポートします。

### Asset Sotreからインストール

extOSCはAsset Storeでも公開さています。
[extOSC \- Open Sound Control \| Input Management \| Unity Asset Store](https://assetstore.unity.com/packages/tools/input-management/extosc-open-sound-control-72005)

## 使い方

インポートしたパッケージのルートにドキュメントが存在しています。またサンプルも充実しており、Package Managerからインポートすることができます。

### OSCの受信

extOSCでOSCを受信するには、`OSCReceiver`コンポーネントを使用します。
`Add Component > extOSC > OSC Receiver`から`OSCReceiver`コンポーネントを追加することができます。`Menu > GameObject > extOSC > OSC Manager`からも`OSCReceiver`コンポーネントと後述する`OSCTransmitter`コンポーネントを持つオブジェクトを作成することが可能です。

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

`Event`コンポーネントを使用してOSCを受信するごとにメソッドを実行することができます。
`Add Component > extOSC > Components > Receiver`から`Event`コンポーネントを追加します。`Event`コンポーネントはデータ型ごとに存在しているので、受信するOSCのデータに合わせて選択します。`Event`コンポーネントの`OSC Receiver`プロパティに使用する`OSCReceiver`を設定します。
![Event_s.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/979b1dc3-b371-e8da-b26f-2587aaa8f677.png)

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

`OSCReceiver`コンポーネントを用いてスクリプトからOSCを受信します。`#OSCReceiver#Bind`でOSCアドレスと受信時に実行するメソッドを紐づけます。紐づけるメソッドはメインスレッドで実行されるのでUnity APIも使用することが可能です。

```c#:ExtOscReceiverScriptSample.cs
using UnityEngine;
using extOSC;

public class ExtOscReceiverScriptSample : MonoBehaviour
{
    [SerializeField] int port = 8000;
    OSCReceiver receiver;

    void Start()
    {
        receiver = gameObject.AddComponent<OSCReceiver>();
        receiver.LocalPort = port;
        receiver.Bind("/extOSC/sample", MessageReceived);
    }

    void MessageReceived(OSCMessage message)
    {
        Debug.Log($"extOSC receive: {message.Values[0].StringValue} {message.Values[1].FloatValue} {message.Values[2].IntValue}");
    }
}
```

### OSCの送信

extOSCでOSCを送信するには、`OSC Transmitter`コンポーネントを使用します。
`Add Component > extOSC > OSC Transmitter`から`OSC Transmitter`コンポーネントを追加するか、先述したように`Menu > GameObject > extOSC > OSC Manager`から`OSCTransmitter`コンポーネントを持つオブジェクトを作成します。

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

`Informer`コンポーネントを使用して、オブジェクトのプロパティ値をOSCで送信できます。
`Add Component > extOSC > Components > Transmitter`から送信するデータ型にあった`Informer`コンポーネントを追加します。`Informer`コンポーネントの`OSC Transmitter`プロパティに使用する`OSCTransmitter`を、`Target`と`Member`に送信するオブジェクトとそのプロパティを設定します。
![Informer_s.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61569/fab9eb5d-17ce-bd3d-2de4-3ccfeb433bf9.png)
デフォルトではプロパティ値に変化があったときのみOSCが送信されますが、`Inform on changed`をオフにすると変化がなくても送信するようになります。


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

`OSCTransmitter`コンポーネントを用いてスクリプトからOSCを送信します。`OSCMessage`を作成して、`OSCTransmitter#Send`で送信します。

```c#:ExtOscTransmitterScriptSample.cs
using UnityEngine;
using extOSC;

public class ExtOscTransmitterScriptSample : MonoBehaviour
{
    [SerializeField] string ipAddress = "127.0.0.1";
    [SerializeField] int port = 8080;
    OSCTransmitter transmitter;

    void Awake()
    {
        transmitter = gameObject.AddComponent<OSCTransmitter>();
        transmitter.RemoteHost = ipAddress;
        transmitter.RemotePort = port;
    }

    void Update()
    {
        var message = new OSCMessage("/extOSC/sample");
        message.AddValue(OSCValue.String("hoge"));
        message.AddValue(OSCValue.Float(123.456f));
        message.AddValue(OSCValue.Int(100));
        transmitter.Send(message);
    }
}
```

### OSCのモニタリング

`Menu > Tools > extOSC > OSC Console`から`OSC Console`ウィンドウを開くことができます。`OSC Cnosole`ウィンドウではextOSCによるOSCの送受信を確認することができます。

### OSCのデータ値のマッピング

extOSCでは送受信するOSCの値をマッピングすることができます。
まず、`Menu > Tools > extOSC > OSC Mapping`から`OSC Mapping`ウィンドウを開き、`Create`ボタンから`OSC Map Bundle`アセットを作成します。`OSC Mapping`ウィンドウでマッピングの設定後にOSCの受信では`OSCReceiver`コンポーネントまたは`Event`コンポーネントに、OSCの送信では`OSCTranmitter`コンポーネントまたは`Informer`コンポーネントの`Map Bundle`プロパティに作成した`OSC Map Bundle`アセットを設定します。


## まとめ

UnityのOSCライブラリであるextOSCの使い方について解説しました。
extOSCは他のOSCライブラリと比較して高機能なので初見では難しく感じますが、実際にはAPIのインターフェースもシンプルで慣れると使いやすそうな印象を受けました。