这玩意是真的难,环境:
macOS 10.15.4
Unity2019.4
Python3.8
首先我们要知道一个API:System.Diagnostics.Process可以打开其他程序。
我期望能在Unity中直接调用一个写好的python脚本。需求很简单,却足足研究了三四个小时。
一开始的思路是,用Unity打开终端,再自动输入一条命令比如python3.8 xxx就可以了。
用百度,发现win上的问题好像不多,都是mac环境的问题,搜到比如这样的:
https://wenwen.sogou.com/z/q718216750.htm
写得很好,说他自己能跑,但是复制过来发现一直Win32Exception。
调研了许久这个FileName的参数,然后发现这篇,说把FileName设置为"open",再去改Arguments参数
http://blog.dou.li/Process-Mac-Win32Exception.html
结果意外地发现下面的代码居然能运行,直接打开了一个Chrome。
Process.Start(new ProcessStartInfo (
"open",
"-a '/Applications/Google Chrome.app' -n --args --no-first-run")
{ UseShellExecute = false });
再试试发现这个也能运行:
Process.Start(new ProcessStartInfo (
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
"--no-first-run")
{ UseShellExecute = false });
可是我把路径换成终端的时候,却不行,我才意识到是路径的问题,路径的问题很好解决,按对应的程序找到Contents/MacOS路径下的可运行文件直接拖到终端里就能获得路径了:
比如现在的终端的路径:/System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal
再把这个路径作为参数传进去就可以在Unity里打开终端了,所以所有Process报Win32Exception的一定是FileName的路径设置错误,这里不建议大家使用open关键词,用默认的这种路径和参数方法去打开一个程序更好。
Process.Start(new ProcessStartInfo (
"/System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal",
"")
{ UseShellExecute = false });
Process打开程序的问题解决了,后面还有一个更大的坑在等着我们。如何把命令作为发给Terminal执行呢?
最上面那张图说是把.py文件作为参数直接传进去就可以,但是我没有成功。
还有人说用下面几行可以,但是我没有成功:
process.StandardInput.WriteLine("echo helloworld");
process.StandardInput.WriteLine("exit"); // if no exit then WaitForExit will lockup your program
process.StandardInput.Flush();
然后我就去深入地研究process.StartInfo.Arguments这个参数,也就是除了文件路径外的第二个参数,到底有什么用,前面加上-a -c -n -args等等前缀都没啥用。
最后我才发现,这个参数居然就是一个文件的意思,即:使用FileName的程序打开Arguments的文件。
那TMD终端怎么可能打得开.py的文件????这不是屁话吗,当然调用了没效果。
理解到这一层,事情就变得容易了,有以下两种方案:
1.使用一个可以直接打开并运行python脚本的程序作为FileName,再把python脚本的路径传入Arguments,就可以顺利运行
2.使用一个终端可以直接打开并运行的文件,用终端打开并运行此文件实现间接调用python3.8 xxx
先说第二种方法,用终端运行shell脚本或者.command脚本应该都是可以的,但是我不会写这俩文件-。-所以此处没有用这个方法实现,如果熟悉shell或者.command的大佬欢迎评论里教我。
此处我用第一种方法实现了本文标题目标,我发现把python脚本用Python Launcher.app打开可以直接运行该脚本。那就容易多了:
Process process = new Process();
process.StartInfo = (new ProcessStartInfo(
"/Applications/Python 3.8/Python Launcher.app/Contents/MacOS/Python Launcher",
"/Users/eevee/Downloads/UnityExcelParser-master/Assets/demo1.py ")
{
UseShellExecute = false,
});
process.Start();
这里注意一下demo1.py 后面有个空格,是通过拖入终端获得的路径,没有空格好像也会有问题。
发现python中的log是可以输出的,但是涉及到一些库引用的时候,却报库找不到的问题No Module named。
尝试修改Python Launcher的设置,却毫无卵用。
最终在这篇找到了解决方法:
在python脚本中,前两行加上:
import sys
sys.path.append('/Users/eevee/opt/anaconda3/lib/python3.8/site-packages')
这个路径是你的python的site-packages的路径,如果不知道这个路径在哪,可以在文件夹中搜以下你调用的库名,一个一个看一看是否有lib/python3.8/site-packages或者lib/python/site-packages之类的,把这个路径填进去之后再运行python脚本,就完全OK了~
网友评论