LoginSignup
5
11

More than 3 years have passed since last update.

PC内でUDPソケット通信(Unityとフォームアプリ)

Posted at

目次

・はじめに
・Windows10(フォームアプリケーション_.NET Framework_C#)の作成
・Unityアプリ(C#)の作成
・結果

はじめに

 別のアプリで処理したデータをUnityに送りたい。UnityはBLEとかサポートしてないので、Windowsで使用する場合は別にアプリを作成する必要があるのだが、数値の引き渡しをどうすべきか?メモリマップトファイルとか使っていたが、Socket通信というのが簡単らしい(もう古いらしい?との情報も…)のでやってみる。
 TCPとUDPの二つの方式のうち、UDPとする。データの品質にはこだわらないからだ。テストのため、
 WindowsフォームアプリからデータをUnityに送信する -> Unityは受け取ったデータを送り返す -> WindowsフォームアプリはUnityからデータを受け取る。
 という形式で作ってみる。
 作ってみた結果は以下のとおり、

Windows10(フォームアプリケーション_.NET Framework_C#)の作成

 まずは【Microsoft Visual Studio Community 2019】から新しいプロジェクト【Windowsフォームアプリケーション_.NET Framework】を作成する。使用する言語は【C#】となる。
 画面も簡単に作る。ラベル二つにボタンが一つ、それにタイマー。それぞれ以下の通り。
  ・ラベル:labelDataFromUnity 受信した数値を表示。
  ・ラベル:labelDataToUnity 送信する数値を表示。
  ・ボタン:buttonDataFromUnity 送信ボタン。ボタンをクリックすると数値を送信する。
  ・タイマー:timer1 ラベルの文字の更新に使用する。intervalが100ms、enabledをtrueに。
 Unityに送る数値は二つ。最初の数値はクリックするごとに一つずつ増える。もう一つは何も変わらない。複数送れるか試すため、二つになっている。
 また、タイマーを用い100msごとにラベルの文字を更新する。

 コードの書き方もいろんなところを参考にコピペして作り上げた。主に参考にしたのは以下のサイト
https://dobon.net/vb/dotnet/internet/udpclient.html
https://garafu.blogspot.com/2015/08/udpclient.html

 以下のようにコードを書いてみる。Tryとかは適当に入れてあるので不十分だが気にしない。

FormsAppSoketUdpQiita
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace FormsAppSoketUdpQiita
{
    public partial class Form1 : Form
    {
        //Formアプリ側
        static string localIpString = "127.0.0.10";
        static int localPort = 8887;
        static IPAddress localAddress = IPAddress.Parse(localIpString);
        static IPEndPoint localEP = new IPEndPoint(localAddress, localPort);
        static UdpClient udp = new UdpClient(localEP);
        //Unity側
        static int unityPort = 8888;
        static IPEndPoint unityEP = new IPEndPoint(localAddress, unityPort);
        //受信用Thread
        static bool isReceiving;
        static string RxDatatext, TxDatatext;
        Thread thread;
        public Form1()
        {
            InitializeComponent();
            udp.Client.ReceiveTimeout = 1000;
            udp.Connect(unityEP);
            isReceiving = true;
            thread = new Thread(new ThreadStart(ThreadMethod));
            thread.Start();
            TxDatatext = "labelDataFromUnity";
            RxDatatext = "labelDataToUnity";
        }

        private void buttonDataToUnity_Click(object sender, EventArgs e)
        {
            if (TxData[0] < 100) TxData[0]++;
            else TxData[0] = 0;
            TxDatatext = TxData[0].ToString() + "," + TxData[1].ToString();
            udp.Send(TxData, 2);
        }
        private static void ThreadMethod()
        {
            while (isReceiving)
            {
                try
                {
                    IPEndPoint remoteEP = null;
                    byte[] data = udp.Receive(ref remoteEP);
                    RxDatatext = data[0].ToString() + " , " + data[1].ToString();
                }
                catch (System.Exception e)
                {
                }
            }
        }
        public static byte[] TxData = {0 ,0};

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (thread != null) thread.Abort();
            if (udp != null) udp.Close();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            labelDataToUnity.Text = TxDatatext;
            labelDataFromUnity.Text = RxDatatext;
        }
    }
}

Unityの作成

 Unity側もやってみる。Textを二つ貼り付けそれぞれ受信したデータと送信するデータが表示される。
 (※受信=送信データなので、値は変わらない)
 textDataToFomApp:送信データ
 textDataFromFomApp:受信データ
 画面はこんな感じで。

 UDP通信用に以下のコードを作った。

LocalUdpReceive
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using UnityEngine.UI;

public class LocalUdpReceive : MonoBehaviour
{
    static string localIpString = "127.0.0.10";
    static int localPort = 8887;
    static IPAddress localAddress = IPAddress.Parse(localIpString);
    IPEndPoint localEP = new IPEndPoint(localAddress, localPort);

    static int unityPort = 8888;
    IPEndPoint unityEP = new IPEndPoint(localAddress, unityPort);
    static bool isReceiving;
    static UdpClient udpUnity;
    Thread thread;

    public Text textDataToFomApp;
    public Text textDataFromFomApp;
    static string Rtext,Ttext;

    void Start()
    {
        udpUnity = new UdpClient(unityEP);
        udpUnity.Client.ReceiveTimeout = 20;
        udpUnity.Connect(localEP);
        isReceiving = true;
        thread = new Thread(new ThreadStart(ThreadMethod));
        thread.Start();
        Debug.Log("start");
        Ttext = "DataToFomApp";
        Rtext = "DataFromFomApp";
    }
    static public byte[] unityData;
    void Update()
    {
        textDataFromFomApp.text = Rtext;
        udpUnity.Send(unityData,2);
        textDataToFomApp.text = Ttext;
    }

    void OnApplicationQuit()
    {
        isReceiving = false;
        if (thread != null) thread.Abort();
        if (udpUnity != null) udpUnity.Close();
    }

    private static void ThreadMethod()
    {
        while (isReceiving)
        {
            try
            {
                IPEndPoint remoteEP = null;
                byte[] data = udpUnity.Receive(ref remoteEP);
                Rtext = data[0].ToString() + " , " +data[1].ToString();
                unityData = data;
                Ttext = unityData[0].ToString() + " , " + unityData[1].ToString();
                Debug.Log(Rtext);
            }
            catch (System.Exception e)
            {
                Debug.Log(e.ToString());
            }
        }
    }
}

結果

 うまく通信できた。メモリマップトファイルよりかなり楽だ。
 ただ、一つ注意がIPアドレスだった。なんでもいいかと思いきやどうもPC内での通信では【127.xx.xx.xx】である必要があるみたいだ。
 このあたりをちゃんと読まねばなぁ。
https://qiita.com/mogulla3/items/efb4c9328d82d24d98e6
 

5
11
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
5
11