如何同时运行Python与Unity3D脚本并实现实时数据交互?
解决方案
一、通过Socket实现Python与Unity的实时坐标同步
Python端(Socket服务器)
编写Socket服务器循环发送处理后的坐标,确保数据格式统一(比如用逗号分隔的字符串):
import socket import time # 替换成你的坐标获取逻辑 def get_camera_coords(): # 示例:模拟实时更新的坐标 return (100 + time.time()*10, 200, 50) HOST = '127.0.0.1' PORT = 65432 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() conn, addr = s.accept() with conn: print(f"已连接: {addr}") while True: coords = get_camera_coords() # 格式化坐标为字符串发送 send_data = f"{coords[0]},{coords[1]},{coords[2]}\n" conn.sendall(send_data.encode('utf-8')) # 控制发送频率,匹配处理帧率 time.sleep(1/60)
Unity端(Socket客户端)
在Unity中编写C#脚本接收数据,解析后实时更新物体位置:
using System; using System.Net.Sockets; using System.Text; using UnityEngine; public class CoordinateSync : MonoBehaviour { private TcpClient _client; private NetworkStream _stream; private StringBuilder _dataBuffer = new StringBuilder(); void Start() { try { _client = new TcpClient("127.0.0.1", 65432); _stream = _client.GetStream(); } catch (Exception e) { Debug.LogError("连接Python服务器失败: " + e.Message); } } void Update() { if (_stream == null || !_stream.DataAvailable) return; byte[] buffer = new byte[1024]; int bytesRead = _stream.Read(buffer, 0, buffer.Length); _dataBuffer.Append(Encoding.UTF8.GetString(buffer, 0, bytesRead)); // 按换行分割完整的坐标数据 while (_dataBuffer.ToString().Contains("\n")) { int newlineIndex = _dataBuffer.ToString().IndexOf("\n"); string coordsStr = _dataBuffer.ToString().Substring(0, newlineIndex); _dataBuffer.Remove(0, newlineIndex + 1); // 解析坐标 string[] parts = coordsStr.Split(','); if (parts.Length == 3 && float.TryParse(parts[0], out float x) && float.TryParse(parts[1], out float y) && float.TryParse(parts[2], out float z)) { // 实时更新物体位置 transform.position = new Vector3(x, y, z); } } } void OnDestroy() { _stream?.Close(); _client?.Close(); } }
运行步骤
- 先启动Python脚本,等待Unity连接
- 在Unity场景中给目标物体挂载上述C#脚本,启动游戏即可实时同步坐标
二、Unity中直接运行Python脚本的方法
方式1:通过系统进程调用Python解释器
在Unity的C#脚本中直接启动Python进程,无需手动运行脚本:
using System.Diagnostics; using UnityEngine; public class RunPythonInUnity : MonoBehaviour { private Process _pythonProcess; void Start() { ProcessStartInfo startInfo = new ProcessStartInfo { // 替换为你的Python解释器路径,比如Windows下的"C:/Python39/python.exe" FileName = "python", // 替换为你的Python脚本路径 Arguments = Application.dataPath + "/Scripts/your_script.py", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true }; _pythonProcess = Process.Start(startInfo); // 监听Python输出用于调试 _pythonProcess.OutputDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) Debug.Log("Python输出: " + e.Data); }; _pythonProcess.ErrorDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) Debug.LogError("Python错误: " + e.Data); }; _pythonProcess.BeginOutputReadLine(); _pythonProcess.BeginErrorReadLine(); } void OnDestroy() { if (_pythonProcess != null && !_pythonProcess.HasExited) _pythonProcess.Kill(); } }
注意:需确保Unity能找到Python解释器,建议使用完整路径避免环境变量问题。
方式2:使用Unity集成Python插件
部分第三方插件(如Python for Unity)可直接在Unity编辑器或运行时嵌入Python环境,无需跨进程调用。这类插件支持直接在Unity中编写、运行Python代码,减少通信开销,但需注意插件与Unity版本的兼容性。
内容的提问来源于stack exchange,提问作者bog
相关产品推荐
相关产品推荐

