Unity 游戏引擎 - 通过 UDP C# 以双浮点形式发送数据

本文关键字:数据 引擎 游戏 通过 UDP Unity | 更新日期: 2023-09-27 17:55:23

大家好,

帖子简介:我需要帮助转换下面的脚本,以双浮点数而不是 UTF8 的形式通过 UDP 发送数据,数据是通过 Unity 3D :)中的命令"transform.position.x"发送的如果您想了解更多信息,请继续阅读。

我的大学硕士项目是开发一个赛车模拟器,我已经通过UDP将车辆位置和旋转数据从模拟软件发送到视觉对象,然后在视觉对象中将传入的数据流分配给3D车辆模型的每个位置或旋转矢量。现在,作为某些系统分析的一部分,我正在尝试测量由通信或以低得多的频率运行的视觉包与仿真软件引起的任何滞后或延迟。

为了测量这一点,我想像往常一样控制视觉环境中的对象,然后让另一个单独的脚本获取对象的坐标并将它们直接发送回另一个端口上的模拟软件,这就是我遇到问题的脚本,因为数据需要作为双浮点数发回。

发送和接收 UDP 脚本最初都来自论坛:https://community.unity.com/t5/Multiplayer-Networking/simple-udp-implementation-send-read-via-mono-c/td-p/154952我尝试修改的UDP发送脚本也如下所示

目前,在这两个中,只使用了接收脚本,当我遇到它时,它已经被修改为接收双浮点数,我正在尝试做的是修改发送脚本以发送双浮点数,它们最初都是为发送和接收 UTF8 编码文本而编写的。

此外,视觉包是Unity 3D,命令"transform.position.x"是获取对象坐标的命令,因此这将是要发送的内容,然后一旦我理解了该方法,我将添加其他位置和旋转矢量。

另外,我

可能应该提到我在编码方面的经验很少,因为这不是我项目的主要部分,但真的很感激一些帮助,因为我对这一点一无所知,现在时间不多了。

提前非常感谢!!

using UnityEngine;
using System.Collections;
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
public class UDPSend : MonoBehaviour {
private static int localPort;
// prefs
private string IP;  // define in init
public int port;  // define in init
// "connection" things
IPEndPoint remoteEndPoint;
UdpClient client;
// gui
string strMessage="";

// call it from shell (as program)
private static void Main()
{
    UDPSend sendObj=new UDPSend();
    sendObj.init();
    // testing via console
    // sendObj.inputFromConsole();
    // as server sending endless
    sendObj.sendEndless(" endless infos 'n");
}
// start from unity3d
public void Start()
{
    init();
}
// OnGUI
void OnGUI()
{
    Rect rectObj=new Rect(40,380,200,400);
    GUIStyle style = new GUIStyle();
    style.alignment = TextAnchor.UpperLeft;
    GUI.Box(rectObj,"# UDPSend-Data'n127.0.0.1 "+port+" #'n"
            + "shell> nc -lu 127.0.0.1  "+port+" 'n"
            ,style);
    // ------------------------
    // send it
    // ------------------------
    strMessage=GUI.TextField(new Rect(40,420,140,20),strMessage);
    if (GUI.Button(new Rect(190,420,40,20),"send"))
    {
        sendString(strMessage+"'n");
    }      
}
// init
public void init()
{
    // Define end point , from which the messages are sent.
    print("UDPSend.init()");
    // define
    IP="127.0.0.1";
    port=16;
    // ----------------------------
    // Send
    // ----------------------------
    remoteEndPoint = new IPEndPoint(IPAddress.Parse(IP), port);
    client = new UdpClient();
    // status
    print("Sending to "+IP+" : "+port);
    print("Testing: nc -lu "+IP+" : "+port);
}
// inputFromConsole
private void inputFromConsole()
{
    try
    {
        string text;
        do
        {
            text = Console.ReadLine();
            // Send the text to the remote client .
            if (text != "")
            {
                // encode data with the UTF8 encoding to binary .
                byte[] data = Encoding.UTF8.GetBytes(text);
                // Send the text to the remote client .
                client.Send(data, data.Length, remoteEndPoint);
            }
        } while (text != "");
    }
    catch (Exception err)
    {
        print(err.ToString());
    }
}
// sendData
private void sendString(string message)
{
    try
    {
        //if (message != "")
        //{
        // encode data with the UTF8 encoding to binary .
        byte[] data = Encoding.UTF8.GetBytes(message);
        // Send the message to the remote client .
        client.Send(data, data.Length, remoteEndPoint);
        //}
    }
    catch (Exception err)
    {
        print(err.ToString());
    }
}

// endless test
private void sendEndless(string testStr)
{
    do
    {
        sendString(testStr);

    }
    while(true);
}
}

Unity 游戏引擎 - 通过 UDP C# 以双浮点形式发送数据

感谢您如此迅速地给出答案,但是我认为这不适用于我的情况,因为模拟软件是基于Modelica的,据我所知,不适用于UTF8编码,这就是我想改变它的原因。

然而,在发布这个之后,我有一个想法,并使用 Youtube 和其他论坛,我能够编写一个脚本,将双浮点数转换为整数值并将它们乘以 1e6,然后将它们作为整数发送和接收,只需在模拟软件中再次将它们除以将它们作为小数返回。

。然后发现我可以使用这种方法将其直接作为双精度发送。

我将在此处发布脚本,以防它对任何人都有用:

using UnityEngine;
using System.Collections;
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
public class LatencyTest : MonoBehaviour {
// Use this for initialization
public void Update () {
    // Get coordinates
    double x = transform.position.x;
    // Create byte array for sending
    byte[] coordinates = BitConverter.GetBytes(x);
    // Define IP Address and Port
    string IP = "127.0.0.1";
    int port= 16;
    Socket client;
    IPEndPoint Dymola;
    //Send to IP Address on the port specified above
    Dymola = new IPEndPoint(IPAddress.Parse (IP), port);
    client = new Socket (AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    client.SendTo (coordinates, Dymola);
    //print (coordinates);
}
}

使用现有的 sendString(字符串消息)函数,你可以做到这一点...

sendString(transform.position.x.ToString());

这会将 x 位置作为 UTF8 字符串发送,您可以在收到 udp 消息后将 UTF8 字符串解析为双精度

...
Double.Parse(string udpMessage);

有关 Double.Parse 的更多参考,请参阅...https://msdn.microsoft.com/en-us/library/fd84bdyt(v=vs.110).aspx

这可能不是最有效的方法,但应该可以很好地处理现有代码。

编辑:要跟进您如何执行此操作以在一个 udp 消息中获取整个位置和旋转,您可以做这样的事情......

string message = transform.position.x + "," 
               + transform.position.y + "," 
               + transform.position.z + ","
               + transform.rotation.x + ","
               + transform.rotation.y + ","
               + transform.rotation.z;
sendString(message);

然后在接收方你会这样做...

string[] messageParts = udpMessage.Split(',');
Vector3 position = new Vector3(
                       Double.Parse(messageParts[0]), 
                       Double.Parse(messageParts[1]),
                       Double.Parse(messageParts[2])
                       );
Vector3 rotation = new Vector3(
                       Double.Parse(messageParts[3]), 
                       Double.Parse(messageParts[4]),
                       Double.Parse(messageParts[5])
                       );

等等....祝你好运。