Python与Unity之间通信实现【Socket实现】

这篇具有很好参考价值的文章主要介绍了Python与Unity之间通信实现【Socket实现】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近做的项目需要实现Python与Unity之间的数据通信,Unity中也有python的插件如IronPython、PyUnity,但是我的python环境和模型都在WSL2中配置了,就选择了用Socket通信的方法实现。
 

一、Python实现连接和传输

思路就是把一个np二维/一维数组转换为list类型,然后两两数字之间插入","作为分割转换为字符串类型,转换为UTF-8编码的字节流,通过socket发送。

python部分的实现:

import numpy as np
import socket
import os

def connect_unity(host,port):
    global sock
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # sock = socket.socket()
    sock.connect((host, port))
    print('连接已建立')

def send_to_unity(arr):
    arr_list = arr.flatten().tolist() # numpy数组转换为list类型
    data = '' + ','.join([str(elem) for elem in arr_list]) + ''  # 每个float用,分割
    sock.sendall(bytes(data, encoding="utf-8"))  # 发送数据
    print("向unity发送:", arr_list)

def rec_from_unity():
    data = sock.recv(1024)
    data = str(data, encoding='utf-8')
    data = data.split(',')
    new_data = []
    for d in data:
        new_data.append(float(d))
    print('从环境接收:',new_data)
    return new_data

# 生成随机数据
data = np.random.random(731,71)

host = '127.0.0.1'
port = 5005   

connect_unity(host,port)

for i in range(output_data.shape[0]):
    send_to_unity(output_data[i])
    rec_from_unity()  # Unity接收数据后再发送下一个

二、Unity实现监听和传输

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine;
public class U2P
{
    private static U2P instance;
    private Socket serverSocket;
    private Socket clientSocket;
    public bool isConnected;

    public static U2P Instance
    {
        get
        {
            if(instance == null)
            {
                instance = new U2P();
            }
            return instance;
        }
    }
    private U2P()
    {
        serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
        // IPAddress ipAddress = IPAddress.Parse("0.0.0.0");
        serverSocket.Bind(new IPEndPoint(ipAddress, 5005));  
        serverSocket.Listen(5); 
        StartServer();
    }
    private void StartServer()
    {
        serverSocket.BeginAccept(AcceptCallback, null);
    }
    private void AcceptCallback(IAsyncResult ar)
    {
        Socket sc = serverSocket.EndAccept(ar); 
        if (clientSocket == null)
        {
            clientSocket = sc; 
            isConnected = true;
            Debug.Log("连接成功");
        }
    }
    public float[] RecData()
    {
        try
        {
            if (clientSocket != null)
            {
                int canRead = clientSocket.Available;
                byte[] buff = new byte[canRead];
                clientSocket.Receive(buff);
                string str = Encoding.UTF8.GetString(buff);
                //Debug.Log(str);
                if (str == "")
                {
                    return null;
                }
                //str = str.Replace("[","").Replace("]","").Replace("\n")Replace("Replace(
                //Debug.Log(“接受消息:”+ str);
                string[] strData = str.Split(',');
                float[] data = new float[strData.Length];
                for (int i = 0; i < strData.Length; i++)
                {
                    data[i] = float.Parse(strData[i]);
                }
                return data;
            }
        }
        catch (Exception ex)
        {
            Debug.LogError("发生错误:"+ex);
            if (clientSocket != null)
            {
                clientSocket.Close(); 
                clientSocket = null; 
                isConnected = false;
                StartServer();
            }
        }
        return null;
    }
    public void SendData(List<float> data)
    {
        try
        {
            if (clientSocket != null)
            {
                string strData = "";
                for (int i = 0; i < data.Count; i++)
                {
                    strData += data[i];
                    if (i != data.Count - 1)
                    {
                        strData += ",";
                    }
                }
                // 使用clientSocket发送strData到服务器的代码
                byte[] dataBytes = Encoding.UTF8.GetBytes(strData);
                clientSocket.Send(dataBytes);
            }
        }
        catch (Exception ex)
        {
            //Debug.LogError("发生错误:”+ex);
            if (clientSocket != null)
            {
                clientSocket.Close();
                clientSocket = null;
                isConnected = false;
                StartServer();
            }
        }
    }
}

调用上述U2P类的代码,挂在到场景中的一个物体中:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.Animations;
using UnityEditor;

public class Connect : MonoBehaviour
{
    private void Update()
    {
        if (U2P.Instance.isConnected)
        {
            float[] data = U2P.Instance.RecData();
            if (data != null)
            {
                print(data.Length);
                print("接收到数据");
                U2P.Instance.SendData(new List<float>(){0}); // 返回0,表示接收到数据
                // TODO: 处理数据
            }
        }
    }
}

需要注意的是,由于这种方法是将float类型(4字节)转换为字符串类型,因此一个浮点数如果是10长度,则需要10个字节,但是socket的单次传输是有限制的,如果需要传输很大数据,所以这里使用分多次连续传输,以一次接受到返回0为接受成功。文章来源地址https://www.toymoban.com/news/detail-509356.html

到了这里,关于Python与Unity之间通信实现【Socket实现】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于python socket实现TCP/UDP通信

    两个应用程序如果需要进行通讯最基本的一个前提就是能够唯一的标示一个进程,我们知道IP层的ip地址可以唯一标示主机,而TCP层协议和端口号可以唯一标示主机的一个进程,这样我们可以利用ip地址+协议+端口号唯一标示网络中的一个进程。能够唯一标示网络中的进程后

    2024年02月16日
    浏览(52)
  • 使用 python socket 实现UDP/TCP网络通信

    目录 目录 1.socket简介 2.创建socket 2.1创建UDPSocket 2.2创建TCPSocket 3.使用UDPSocket发送数据并接收 4.使用UDPSocket发送广播 5.UDPSocket聊天器 (多线程实现消息的收发功能) 6.使用TCPSocket建立客户端 7.使用TCPSocket建立服务端        socket(简称:套接字),是支持TCP和UDP(网络传输方式

    2023年04月10日
    浏览(65)
  • socket概述 python中如何使用TCP/UDP协议实现通信-教程

    很多编程语言中,都 使用scoket套接字实现网络通信。 Socket是对TCP/IP协议的封装,Socket本身就是一个调用接口(API),方便程序员用Socket使用TCP/IP协议簇,实现网络通信。 不同编程语言,shiyongSocket通信的语法有所区别,但基本原理类型相似。 它的两种方式,分别是TCP和UDP协

    2024年02月13日
    浏览(42)
  • SpringBoot项目整合WebSocket+netty实现前后端双向通信(同时支持前端webSocket和socket协议哦)

    目录   前言 技术栈 功能展示 一、springboot项目添加netty依赖 二、netty服务端 三、netty客户端 四、测试 五、代码仓库地址   专属小彩蛋:前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站(前言 - 床长人工智能教程

    2024年02月12日
    浏览(50)
  • Unity学习之Socket通信

    简单的一对一通信,客户端向服务器传输字符串,具体操作如下: 在VisualStudio中创建一个新工程,在工程中编写服务器逻辑,代码如下: 在unity中创建一个脚本,即Client.cs,具体代码如下: 在Hierarchy面板中创建一个空的游戏对象,将Client脚本绑定在游戏对象上。创建的面板

    2024年02月12日
    浏览(33)
  • 了解JS三种实时通信方式——Eventsource、websocket与socket.io之间的差异和优缺点

    EventSource EventSource 是一种轻量级的 API,用于获取来自服务器的实时事件。它是 WebSockets 的替代方案,因为它比 WebSockets 更简单,更适合处理服务器向客户端发送数据的情况。使用 EventSource ,只有服务器能够发送消息,所以它更安全。但是,它不支持双向通信或客户端发送消

    2024年02月08日
    浏览(49)
  • WinForm內嵌Unity(Socket通信)

    最近有需求要实现WinForm和Unity交互,也就是通信,查过几个方案有用UnityWebPlayer Control组件的(由于版本问题所以我没尝试),也有把Winform打包成dll动态链接库然后unity内引入的,还有打包Unity.exe然后Winform内嵌入的,后面两种都可以。 一.Winform打包成dll动态链接库然后unity内引

    2024年02月13日
    浏览(35)
  • 【Unity】Socket网络通信(TCP) - 最基础的客户端通信流程

    这篇文章主要内容是客户端与服务器通信的内容,服务端代码可以看我的这一篇文章【Unity】Socket网络通信(TCP) - 最基础的C#服务端通信流程 客户端与服务器的整个流程比较相似,客户端会更加简单一些: 创建socket 连接服务器 收发消息 释放socket,关闭连接 和服务端创建

    2024年02月03日
    浏览(47)
  • 【Unity】Socket网络通信(TCP) - 最基础的C#服务端通信流程

    我这里新建了一个C#控制台项目来写服务端代码。 下面是基于C# Socket的最基础服务端通信流程: 创建服务端Socket对象 绑定IP地址和端口 设置最大监听客户端数量 等待客户端连接 收发消息 释放连接 基于上面流程就能实现一个最简单并且能和客户端通信的服务器程序,每个步

    2023年04月16日
    浏览(64)
  • 【Unity3d】Unity与iOS之间通信

    在Unity开发或者SDK开发经常遇到Unity与移动端原生层之间进行通信,这里把它们之间通信做一个整理。 关于Unity与Android之间通信,参考【Unity3d】Unity与Android之间通信 Unity调用Objective-C 主要分三个步骤: (一)、在xcode中定义要被unity调用的函数 新建一个类,名字可以任意,比如

    2024年02月01日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包