32
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Unity OSCを使いOSCを送受信する

Unity OSC

以前書いた記事は間違っていた箇所もあったので、もう一度UnityOSCに関する投稿。
トリガーによって流れる映像を二つのアプリケーションで同期するためにOSCを使う。同時に音は8chで出力するためにMAXにも信号を送る。

VR_System.png

IP, Port

受信するならCreateServer()、送信するならCreateClient()
複数の送信先を作れるのがoFのOSCSenderSampleなどより便利かもしれない。

OSCHandler.cs
    public void Init()
    {
        // this is for the receiver app
        CreateServer("UnityReceiver", 12345);

        // those are for the sender app
        //CreateClient("Unity", IPAddress.Parse("169.254.182.100"), 12345);
        //CreateClient("MAX", IPAddress.Parse("169.254.182.100"), 12346);
    }

Code

Start()で

OSCHandler.Instance.Init ();

後はUpdate中に作ったメソッド入れるとわかりやすいのでは(受信側だととくに)。

public class SOMECLASS : MonoBehaviour {
    void Start() {
        OSCHandler.Instance.Init ();
    }
    void Update() {
        // if sender app..
        CheckOSCSend();
        // if receiver app..
        //ListenOSC();
    }
}

Sender

任意のMonoBehaviour継承クラスのUpdate()メソッドにListenToOSC()などを追加。
キーが一度押されただけでも複数のOSCを送ってしまっていたのでPreventRedundantOSC()という関数を追加。一度OSCを送ったら送信不可能にしている。
SendReset()はMAX側だけにkeydownから一定時間経過したらOSCを送る処理。

    bool isOSCReady = true;

    void CheckOSCSend(){
        if (
            (Input.anyKey) &&
            (isOSCReady)
        ) {
            string inputStr = Input.inputString;
            Debug.Log (inputStr);
            string allCharChunk = "123456789";
            if (allCharChunk.Contains(inputStr)) {
                Debug.Log (inputStr + " is pressed.");
                int sentInt;
                int.TryParse (inputStr, out sentInt);
                OSCHandler.Instance.SendMessageToClient ("Unity", "/Audio", sentInt);
                OSCHandler.Instance.SendMessageToClient ("MAX", "/Audio", sentInt);
                // set timer
                StartCoroutine(SendReset(sentInt));
                StartCoroutine (PreventRedundantOSC());
            }
            Debug.Log (inputStr);
        }
    }

    // prevent sending OSC multiple times with just one keydown
    IEnumerator PreventRedundantOSC() {
        isOSCReady = false;
        yield return new WaitForSeconds (2.0f);
        isOSCReady = true;
    }

    IEnumerator SendReset(int movieType) {
        float[] waitTimes = new float[9] {4.7f, 4.0f, 5.2f, 5.55f, 4.3f, 9.0f, 4.6f, 4.5f, 4.5f};
        int targetNum = movieType - 1;
        yield return new WaitForSeconds (waitTimes [targetNum]);
        OSCHandler.Instance.SendMessageToClient ("MAX", "/Audio", 0);
    }

Receiver

任意のMonoBehaviour継承クラスのUpdate()メソッドにListenToOSC()などを追加。
他のクラスに渡す処理を考えたりするとOSCController.csなどを作るよりも、OSCを送る・受ける処理が必要なクラスにそのまま追加してもいいのかもしれない。今回はキーボードの1~9を押されたらその値を送るというものだった。その値によって流れる映像が変わるというもの。(映像処理はRenderPitcher()が実行している)

    // methods related to osc goes from here.
    void listenToOSC(){
        OSCHandler.Instance.UpdateLogs ();
        Dictionary<string, ServerLog> servers = new Dictionary<string, ServerLog>();
        servers = OSCHandler.Instance.Servers;

        foreach (KeyValuePair<string, ServerLog> item in servers) {
            Debug.Log (item.Value.log.Count);
            if (item.Value.log.Count > 0) {
                Debug.Log ("count is more than zero");
                int lastPacketIndex = item.Value.packets.Count - 1;

                string s1 = "123456789";
                string s2 = item.Value.packets [lastPacketIndex].Data [0].ToString ();
                if (
                    (s1.Contains(s2)) &&
                    (item.Value.packets[lastPacketIndex].Address == "/Audio")
                ) {
                    RenderPitcher(s2);
                    // reset
                    item.Value.packets[lastPacketIndex].Address = "/reset";
                    Debug.Log ("change view");
                }
            }
        }
        OSCHandler.Instance.UpdateLogs ();
    }

Tips

Wifi

ここが一番意味がありそうだが、Wifi経由だとMAXにはOSC受けれるがUnityでは受信できないという問題があった。有線にしたら解決した。UE4でもOSC使っていたりするのだが普通に無線通信で機能していた。UnityよりもPlugin(UnityOSC)の問題なのかもしれない。

Version

UnityVersion最新(たしか5.34)で作ったプロジェクトを他PCのUnityEditor(ver5.0)でrebuildしたらOSC通信できないという問題があった。複数PC使うシステムなんかではとくにversion気にしていないと無駄に時間をかけてしまいそう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
32
Help us understand the problem. What are the problem?