ict.shenzhi/Assets/Scripts/cxx/python/UnityCallPython.cs

155 lines
4.3 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using UnityEngine;
using System.IO;
using System.Linq;
public class UnityCallPython : MonoBehaviour
{
public static UnityCallPython instance;
Process process;
/// <summary>
/// 主体机器人
/// </summary>
Robot robot;
private void Awake()
{
instance=this;
string[] lines = new string[8];
lines[0] = "home = " + Application.streamingAssetsPath + @"\cxx\Python37";
lines[1] = "implementation = CPython";
lines[2] = "version_info = 3.7.8.final.0";
lines[3] = "virtualenv = 20.24.5";
lines[4] = "include-system-site-packages = false";
lines[5] = "base-prefix = " + Application.streamingAssetsPath + @"\cxx\Python37";
lines[6] = "base-exec-prefix = " + Application.streamingAssetsPath + @"\cxx\Python37";
lines[7] = "base-executable = "+ Application.streamingAssetsPath + @"\cxx\Python37\python.exe";
File.WriteAllLines(Application.streamingAssetsPath + @"\cxx\venv\pyvenv.cfg", lines);
}
private void OnDestroy()
{
if (process != null && !process.HasExited)
{
process.Kill();
process = null;
}
}
/// <summary>
/// 启动颜色识别
/// </summary>
[ContextMenu("启动颜色识别")]
public void StartColorRead(Robot robot)
{
this.robot = robot;
CallPythonBase();
}
/// <summary>
/// 停止颜色识别
/// </summary>
[ContextMenu("停止颜色识别")]
public void StopColorRead()
{
OnDestroy();
}
/// <summary>
/// Unity 调用 Python
/// </summary>
/// <param name="pyScriptPath">python 脚本路径</param>
/// <param name="argvs">python 函数参数</param>
private void CallPythonBase()
{
if (process == null || process.HasExited)
{
process = new Process();
process.StartInfo.FileName = "\"" + Application.streamingAssetsPath + @"\cxx\venv\Scripts\python.exe" + "\"";
process.StartInfo.UseShellExecute = false;
process.StartInfo.WorkingDirectory = Application.streamingAssetsPath + @"\cxx\venv\Scripts\cxx";
process.StartInfo.Arguments = "-u ColorDetect.py"; // 路径+参数
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true; // 不显示执行窗口
process.OutputDataReceived += new DataReceivedEventHandler(GetData);
process.ErrorDataReceived += new DataReceivedEventHandler(GetError);
process.Exited += GetExit;
// 开始执行,获取执行输出,添加结果输出委托
process.Start();
Task.Run(() => { ReadPythonData(); });
process.BeginErrorReadLine();
UnityEngine.Debug.Log("开始");
}
}
/// <summary>
/// 读取python输出值
/// </summary>
void ReadPythonData()
{
//异步
var task=process.StandardOutput.ReadLineAsync();
task.Wait();
if(!string.IsNullOrEmpty(task.Result))
{
UnityEngine.Debug.Log(task.Result);
if(robot!=null)
{
robot.PlayColorAction(task.Result);
}
}
ReadPythonData();
//同步
//while(true)
//{
// string str = process.StandardOutput.ReadLine();
// if (!string.IsNullOrEmpty(str))
// {
// UnityEngine.Debug.Log(str);
// }
//}
}
/// <summary>
/// 输出结果委托
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void GetData(object sender, DataReceivedEventArgs e)
{
UnityEngine.Debug.Log("GetData");
// 结果不为空才打印(后期可以自己添加类型不同的处理委托)
if (!string.IsNullOrEmpty(e.Data))
{
UnityEngine.Debug.Log(e.Data);
}
}
void GetError(object sender, DataReceivedEventArgs e)
{
UnityEngine.Debug.Log("GetError");
if (!string.IsNullOrEmpty(e.Data))
{
UnityEngine.Debug.LogError(e.Data);
}
}
void GetExit(object sender, EventArgs e)
{
UnityEngine.Debug.Log("finished.");
}
}