目次
・はじめに
・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ごとにラベルの文字を更新する。WindowsフォームアプリとUnity間でソケット通信
— いっちー (@get_itchy_feet) April 11, 2020
PC内のアプリ間でUDPの通信ができるようになった。 pic.twitter.com/A3ivxNi6rO

以下のようにコードを書いてみる。Tryとかは適当に入れてあるので不十分だが気にしない。
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通信用に以下のコードを作った。
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