最近需要在unity中实现一些数据处理相关的东西,但C#做数据处理感觉比起Python麻烦很多,于是就去找了找在unity中使用Python的办法。很可惜的是,找到的办法要么就是太过于复杂,难以实现,要么就是在我的电脑无法实现,唯一实现的ironpython,还不支持Python3。
没办法,只能自己找了一个取巧的办法,勉强算是满足了使用要求,方法比较原始,有大佬知道更好的办法还望告知。
具体的做法就是,先用Python将自己要使用的功能封装好,用pyinstaller打包成一个exe文件,exe文件接受一个参数(如果需要的话)。然后用C#去调用这个exe文件,并传入所需要的必要的参数。像我自己由于要实现的功能,需要读取几个在unity运行中产生的文件,所以我是将那些文件保存后,再将需要用到的这些文件的路径保存在一个TXT文件中,然后在调用exe文件时直接传入TXT文件的路径作为参数,然后就可以通过读取该TXT文件获取到所有需要的文件了。这里的注意点是,路径最好用Application.dataPath(),这样方便在编辑器和打包出的结果中都能使用,在编辑器中它返回的路径就在Asset文件夹中,而打包的结果则在Data文件夹中。
下面是C#调用的示例代码
public static string CallCMD(string _command, string _arguments) // 定义一个名为CallCMD的静态方法,它接受两个字符串参数,分别表示外部程序的路径和参数,并返回一个字符串值,表示外部程序的输出结果
{
ProcessStartInfo psi = new ProcessStartInfo(_command, _arguments); // 创建一个ProcessStartInfo对象,用来设置启动进程的信息,将外部程序的路径和参数赋值给相应的属性
psi.CreateNoWindow = true; // 设置CreateNoWindow属性为true,表示不显示窗口
psi.RedirectStandardOutput = true; // 设置RedirectStandardOutput属性为true,表示重定向标准输出
psi.UseShellExecute = false; // 设置UseShellExecute属性为false,表示不使用Shell执行
Process p = Process.Start(psi); // 使用Process类的Start方法,根据ProcessStartInfo对象的设置启动进程,并返回一个Process对象,表示该进程
return (p.StandardOutput.ReadToEnd()); // 使用Process对象的StandardOutput属性获取标准输出流,并使用ReadToEnd方法读取全部内容,然后返回该字符串值
}
public void getScores()
{
string exepath = "scorescontrol\\main.exe";
exepath = Path.Combine(Application.dataPath, exepath);
string arguments = "paths.txt"; // 定义一个字符串变量,存储要传入的参数,用空格分隔
arguments = Path.Combine(Application.dataPath, arguments);
string content = CallCMD(exepath, arguments); // 调用CallCMD方法,并将外部程序的路径和参数作为参数传入,然后将返回值输出
}
还要注意的是,由于这里调用的是命令行窗口,所以这里得到的exe运行结果并不是Python文件中对应的return值,而是print()输出的内容。