見出し画像

【Unity】UDP通信する

最近はUnityを使った通信シリーズの記事が続いていますが、今回も流れを汲んでUDP通信を試していきたいと思います。

前回の記事で扱ったOSC通信は一般にUDPプロトコルが使われており、UDP自体は原始的なプロトコルでもあるため、外部のライブラリ等を用いずに標準ライブラリで実装することが可能になっています。それでは早速やっていきましょう!

1. 受信側

すぐにコードの実装に移りたいところすが、UDP通信に限らずネットワーク通信全般におけるお作法として、受信には非同期処理やメインスレッド以外での処理が必要になります。

Debug.Logを出力するだけであれば特に意識する必要はありませんが、折角Unity上で行っているので、メッセージを受信したらシーンにデータを反映させたくなります。そこで今回はUniRxを使って受信データを処理していきます。UniRxのインポートは事前に済ませておいてください。

コードは以下のようになります。

using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UniRx;
using UnityEngine.UI;

public class ServerExample : MonoBehaviour
{
   private UdpClient udpClient;
   private Subject<string> subject = new Subject<string>();
   [SerializeField] Text message;


   void Start() {
       udpClient = new UdpClient(9000);
       udpClient.BeginReceive(OnReceived, udpClient);

       subject
           .ObserveOnMainThread()
           .Subscribe(msg => {
               message.text = msg;
           }).AddTo(this);
   }

   private void OnReceived(System.IAsyncResult result) {
       UdpClient getUdp = (UdpClient) result.AsyncState;
       IPEndPoint ipEnd = null;

       byte[] getByte = getUdp.EndReceive(result, ref ipEnd);

       var message = Encoding.UTF8.GetString(getByte);
       subject.OnNext(message);

       getUdp.BeginReceive(OnReceived, getUdp);
   }

   private void OnDestroy() {
       udpClient.Close();
   }
}

9000番ポートで待機し、UniRxのsubjectを使ってイベントの発行と購読を行います。スクリプトは適当なオブジェクトにアタッチしてください。アタッチ後、シーンにTextを配置してスクリプトに割り当てます。

もし、UniRxを使用しない場合は変数に受信データを格納し、Update()で使用すると良いでしょう。

2. 送信側

送信側は任意のタイミングで送信すれば良いのでとてもシンプルです。以下のスクリプトを適当なオブジェクトにアタッチしてください。

using UnityEngine;
using System.Net.Sockets;
using System.Text;

public class ClientExample : MonoBehaviour
{
   private string host = "192.168.1.9";
   private int port = 9000;
   private UdpClient client;

   void Start() {
       client = new UdpClient();
       client.Connect(host, port);
   }


   void Update() {
       if (Input.GetKeyDown(KeyCode.S)) {
           Debug.Log("Send");
           var message = Encoding.UTF8.GetBytes("Hello World!");
           client.Send(message, message.Length);
       }
   }

    private void OnDestroy() {
       client.Close();
   }
}

3. 実行

受信側と送信側をそれぞれ実行し、送信側から「s」キーを押して受信側のテキストが変われば成功です。

スクリーンショット 2021-06-28 181044

もし、うまくいかない場合はファイヤーウォールの設定を確認します。前回の記事で詳しく触れているので参考にしてみてください。

4. おわりに

OSCと比較するとUDPを直接扱う機会は少ないかもしれませんが、C#の標準ライブラリのみで気軽に記述できる点や、通信の相手側が直のUDP通信にしか対応していない場合もありますので、手段の1つとして利用できると良いでしょう。🌱

5. 参考



いいなと思ったら応援しよう!