LoginSignup
15
15

More than 5 years have passed since last update.

UnityOSCについて学ぶ

Posted at

はじめに

今回はUnityOSCの学習がてらクライアントからサーバへのデータ送信を伴う簡単なアプリケーションを作ってみました。即興なのでアプリのクオリティは悪しからず笑

OSCとは

OSC(Open Sound Control)とは通信プロトコルの一種で、本来は電子楽器の制御に使われていたましたが、今ではその他にも様々な用途に使われているらしいです。クライアントからサーバにデータを送信するようなアプリケーションでは有効な手段の1つだと思います。UnityにもOSC通信を行うためのパッケージがあるようなので、今回はそのうちの1つを使ってみました。

作成したアプリケーション

クライアント側
はじめにサーバ側のPCのIPアドレスと使用するポート番号を入力します。
Startボタンを押したらゲームスタートです!
スクリーンショット 2019-01-12 22.26.59.png

この画面になったら1〜9の数字を入力します。
スクリーンショット 2019-01-12 22.27.25.png

サーバ側
こちらではクライアント側で入力した数字に対応した部分が黄色に変化します。
全てが黄色に変わると全て白に戻ります。
スクリーンショット 2019-01-12 22.27.58.png

それでは早速UnityOSCを使うための準備から始めましょう!

準備

jorgegarcia/UnityOSCをダウンロードします。
その中のsrcフォルダをUnityのプロジェクトのAssetsフォルダにインポートします。
これをクライアント側とサーバ側両方で行なったら準備は完了です!

実装

それではクライアント側とサーバ側に分けて実装の説明をしていきます。

クライアント側

まずクライアントからです。
はじめにインポートしたsrcフォルダの中にあるOSCHandler.csのInit関数を編集します。
InputFieldに入力したIPアドレスとポート番号を取得しipNumとportNumに代入しています。

OSCHandler.cs
public void Init()
{
    string ipNum = FindObjectOfType<GameController>().ip;
    int portNum = FindObjectOfType<GameController>().port;
    //Initialize OSC clients (transmitters)
    //Example:      
    CreateClient("OSCClientTest", IPAddress.Parse(ipNum), portNum);

    //Initialize OSC servers (listeners)
    //Example:
    //CreateServer("OSCTest", 8001);
    }

続いてOSCClientTest.csという新たなスクリプトを作成します。
キーボードで押した数字をサーバ側に送信するためのスクリプトです。

OSCClientTest.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityOSC;

public class OSCClientTest : MonoBehaviour
{

    bool startFlag = false;
    void Start()
    {
        startFlag = FindObjectOfType<GameController>().flag;
        OSCHandler.Instance.Init();
    }

    void Update()
    {
        // ゲームがスタートしてから送信可能になる
        if (startFlag)
        {
            if (Input.anyKeyDown)
            {
                string inputStr = Input.inputString;
                string allNumStr = "0123456789";
                if (allNumStr.Contains(inputStr))
                {
                    Debug.Log(inputStr + " is pressed");
                    int sentInt;
                    int.TryParse(inputStr, out sentInt);
                    OSCHandler.Instance.SendMessageToClient("OSCClientTest", "/Int", sentInt);
                }
            }
        }
    }
}

これは本質的ではないですが、InputFieldにIPアドレスとポート番号を入力してゲームを始めるまでの部分を管理するスクリプトです。

GameController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GameController : MonoBehaviour {

    public InputField ipField;
    public InputField portField;
    public Button startButton;
    public GameObject client;
    public GameObject canvas2;

    public string ip;
    public int port;

    public bool flag = false;

    void Start () {
        startButton.onClick.AddListener(ConnectToServer);
    }

    // IPアドレスとポート番号を入力してサーバと接続する関数
    public void ConnectToServer()
    {
        ip = ipField.text;
        port = int.Parse(portField.text);
        flag = true;
        GameObject.Find("Canvas").SetActive(false);
        canvas2.SetActive(true);
        client.SetActive(true);
    }
}

サーバ側

次にサーバ側です。
クライアント側と同じくOSCHandler.csを以下のように編集します。

OSCHandler.cs
public void Init()
    {
        //Initialize OSC clients (transmitters)
        //Example:      
        //CreateClient("SuperCollider", IPAddress.Parse("127.0.0.1"), 5555);

        //Initialize OSC servers (listeners)
        //Example:

        CreateServer("OSCServerTest", 8001);
    }

クライアントから送信されたデータを受信するスクリプトOSCServerTest.csを作成します。

OSCServerTest.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityOSC;

public class OSCServsrTest : MonoBehaviour {

    public Image[] images;
    string s1 = "123456789";

    int currentDataLen = 0;

    void Start () {
        OSCHandler.Instance.Init();
    }

    void Update()
    {
        OSCHandler.Instance.UpdateLogs();
        Dictionary<string, ServerLog> servers = new Dictionary<string, ServerLog>();
        servers = OSCHandler.Instance.Servers;
        foreach (KeyValuePair<string, ServerLog> item in servers)
        {
            // データを新たに受信したら
            if (currentDataLen != item.Value.packets.Count)
            {
                currentDataLen = item.Value.packets.Count;

                // 最後に受信したデータのIndexを取得
                int lastPacketIndex = item.Value.log.Count - 1;

                // 最後に受信したデータを取得
                string s2 = item.Value.packets[lastPacketIndex].Data[0].ToString();

                // 取得したデータの数字に対応する部分を黄色に変更
                if (s1.Contains(s2))
                {
                    Debug.Log("s2: " + s2);
                    int i = int.Parse(s2);
                    images[i - 1].color = new Color(255.0f, 255.0f, 0f);
                    s1 = s1.Replace(s2, "");

                    // 9つの数字の色が全て変更したら全て白に戻す
                    if (s1 == "")
                    {
                        for (int j = 0; j < images.Length; j++)
                        {
                            images[j].color = new Color(255.0f, 255.0f, 255.0f);
                            s1 = "123456789";
                        }
                    }
                }
            }
        }
    }
}

おわりに

今回はUnityOSCの使い方について学習しました。
今回作成したアプリケーションはこちらに上げてあります。

UnityOSCを用いれば、
- スマホをコントローラーにしたPCゲーム
- Leap Motionなどを用いてスマホのゲームを操作する
など色々面白いことができるのではないでしょうか。

これ使って何か面白いコンテンツ作ってみたいですね〜

15
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
15