前提・実現したいこと
unityでUDP受信をしたいのですが、
一回一回unityの再生ボタンを押さないと値が更新されません(再生ボタンを押したら値が更新される)
下の画像で1,2,3とあるところが、三角の再生ボタンを押して出力された値です
python側ではデータの変化を受信できているのですが、unityでそれができません。
UDP通信に使うもとになるものはUDP通信を使っています。
これをfloat配列をおくるようにパケットを書き直しました。
その結果下のpythonプログラムでは常に正しい値が出力されていました
python
1import socket #通信用 2import struct 3address = ('', 40002) #通信を受け付けるIPアドレスと受信に使うポート番号の設定.127.0.0.1とするとPC内通信. 4 5udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #udpという名前のUDPソケット生成 6udp.bind(address) #udpというソケットにaddressを紐づける 7 8while True: #受信ループ 9 try: 10 rcv_byte = bytes() #バイトデータ受信用変数 11 rcv_byte, addr = udp.recvfrom(1024) #括弧内は最大バイト数設定 12 #msg = rcv_byte.decode() #バイトデータを文字列に変換 13 14 # bytes -> double(8byte浮動少数) x 3 15 res = struct.unpack('<fffffffffffffffff', rcv_byte) 16 print(res) 17 18 except KeyboardInterrupt:#強制終了を検知したらUDPソケットを閉じて終了 19 udp.close()
しかしunityのほうだと一回一回再生ボタンを押さなければ出力が更新されません(pythonとC#のUDP通信に違いがある?
該当のソースコード
受信用プログラム
C#
1using forudp; 2public class udp_rec : MonoBehaviour 3{ 4 private UDP commUDP = new UDP(); 5 //commUDP.init(int型の送信用ポート番号, int型の送信先ポート番号, int型の受信用ポート番号); 6 7 // Start is called before the first frame update 8 void Start() 9 { 10 commUDP.init(40005, 40002, 40002); 11 } 12 void Update() 13 { 14 15 commUDP.start_receive(); 16 var b = commUDP.rcv_float_arr; 17 for (int i = 0; i < 5; i++) 18 { 19 Debug.Log("[" + b[i * 3].ToString() + "," + b[i * 3 + 1] + "," + b[i * 3 + 2] + "]"); 20 } 21 }
下がUDP通信のもととなるものです。
using System.Text; using System.Net;//for UDP using System.Net.Sockets; //for UDP using System.Collections.Generic; using System; namespace forudp //namespaceは本体に合わせて要修正 { public class UDP { private UdpClient udpForSend; //送信用クライアント private string remoteHost = "localhost";//送信先のIPアドレス private int remotePort;//送信先のポート private UdpClient udpForReceive; //受信用クライアント public string rcvMsg = "ini";//受信メッセージ格納用 public float rcvMsg_xyz = 0; private System.Threading.Thread rcvThread; //受信用スレッド public List<float> rcv_float_arr = new List<float>(); //List<float> rcv_float_arr = IEnumerable.ToList(); public UDP() { } public bool init(int port_snd, int port_to, int port_rcv) //UDP設定(送受信用ポートを開きつつ受信用スレッドを生成) { try { udpForSend = new UdpClient(port_snd); //送信用ポート remotePort = port_to; //送信先ポート udpForReceive = new UdpClient(port_rcv); //受信用ポート rcvThread = new System.Threading.Thread(new System.Threading.ThreadStart(receive_xyz)); //受信スレッド生成 //rcvThread = new System.Threading.Thread(new System.Threading.ThreadStart(receive)); //受信スレッド生成 return true; } catch { return false; } } public void send(string sendMsg) //文字列を送信用ポートから送信先ポートに送信 { try { byte[] sendBytes = Encoding.ASCII.GetBytes(sendMsg); udpForSend.Send(sendBytes, sendBytes.Length, remoteHost, remotePort); } catch { } } public void send_xyz_arr(float[] sendMsg) //float配列を送信用ポートから送信先ポートに送信 { try { byte[] sendBytes = new byte[sendMsg.Length]; byte[] rv = new byte[4*sendBytes.Length]; for (int i = 0; i < sendMsg.Length; i++) { sendBytes = BitConverter.GetBytes(sendMsg[i]); System.Buffer.BlockCopy(sendBytes, 0, rv, i*4, sendBytes.Length); } udpForSend.Send(rv, rv.Length, remoteHost, remotePort); } catch { } } public void receive_xyz() //受信スレッドで実行される関数 { IPEndPoint remoteEP = null;//任意の送信元からのデータを受信 while (true) { try { byte[] rcvBytes = udpForReceive.Receive(ref remoteEP); for (int i = 0; i < rcvBytes.Length; i++) { var a = BitConverter.ToSingle(rcvBytes, i * 4); rcv_float_arr.Add(a); } } catch { } } } public void start_receive() //受信スレッド開始 { try { rcvThread.Start(); } catch { } } public void stop_receive() //受信スレッドを停止 { try { rcvThread.Interrupt(); } catch { } } public void end() //送受信用ポートを閉じつつ受信用スレッドも廃止 { try { udpForReceive.Close(); udpForSend.Close(); rcvThread.Abort(); } catch { } } } }
試したこと
最初unityで受け取ろうとしていたのですが、毎回再生ボタンを押さないといけないことから正しい値は届いていることがわかったのですが、念の為pythonで受信用プログラムを動かしました。
その結果正しい値が届いていました。
おそらくunityのUDP通信に問題があると思っているのですが何がおかしいのでしょうか
udp_recのほうのupdate関数で毎フレームごと
変化するUDPの値を受け取ることができると考えているのですが、それが更新されていない理由が検討もつきません
いろいろ試したのですが結局解決できませんでした
よろしくお願いします
補足情報(FW/ツールのバージョンなど)
unity 2018 3.14
windows10
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/07/04 02:30