工作中有一个需求,就是将unity工程放在服务器上,自动执行一些打包任务。这时候就需要启动一个没有GUI的unity,并自动执行其中的打包脚本。
1.官网的说明:
2.一般的调用方法:
2.1创建入口方法
首先在工程力写一个非mono的C#脚本。在里面创建一个类和一个静态方法。这个静态方法不能有参数。
2.2启动unity调用方法。
之后在批处理脚本里调用如下命令
"C:\Program Files\Unity\Hub\Editor\2020.3.9f1c1\Editor\Unity.exe" -quit -batchmode -projectPath "You Project Path" -logFile "D:\UnityFile\NewRemoteProject\__kellylog.txt" -executeMethod TestCmd.Func1
第一段路径是所需要启动的unity版本的unity.exe。可以通过unityhub来查找路径。
//插入图片
“-quit” :代表运行完毕后关闭unity。
“-batchmode” :以批处理模式运行 Unity。
“-projectPath ” : 之后跟着你要打开的工程的路径
“-logFile” : 可选项,如果需要打出unitylog的话,之后跟着你要保存的log文件路径
“-executeMethod ” :之后跟着你要调用的入口方法。如果在自定义的命名空间的话,要从命名空间开始写。
如何向入口方法里传参数
由于只能调用无参的静态方法,但通过传参控制程序又是很常见的需求,例如登录账号。所以要另辟蹊径处理。
一种方法是写个配置文件,在程序运行时去读即可,还有一种方法是通过环境变量来设置。
通过环境变量设置程序参数
首先在C#脚本里读取环境变量
var EnvVal = System.Environment.GetEnvironmentVariable("Env1");
这个方法有重载。默认是读取该进程的环境变量。也可以通过重载读取用户和系统的环境变量。
之后只要在批处理脚本里设置环境变量就行了。
set Env1=1234
注意空格也会被算在批处理的变量和值里,所以等号两边不能有空格。
3.使用中遇到的坑
1.如果用了EditorCoroutine插件里的开启协程方法
项目中原来都用了EditorCoroutine插件来在Editor下用协程方法,用来做异步。但到了批处理模式下,由于没有了GUI,在开启协程后需要手动刷新Editor下的update方法。如下,传入一个bool值来控制是否继续刷新等待。
//主方法里
bool isComplete = false;
EditorCoroutineUtility.StartCoroutineOwnerless(CorFun(()=> { isComplete = true; }));
StartUpdate(ref isComplete);
private static void StartUpdate(ref bool isCompleted)
{
while (!isCompleted)
{
EditorApplication.update?.Invoke();
}
}
注意这时Editor的Update里的方法在主线程里执行,异步变为同步。
当然也可以保持异步形式,就是主线程持续刷新Editor的Update,把业务代码放在子线程里,例如用BeginInvoke等。但反过来不行,因为Editor的Update只能在主线程里调。
实际上在批处理模式下,editorApplicants.update 还是会被隔一段时间调用。并不用直接调代码去刷。之前之所以一调协程方法就直接退出了,是因为在批处理里加了-quit,导致协程方法一调用,就开始继续执行原方法的下一行,如果原方法完成,Unity就自动关闭,不管协程是否还在工作。解决方法是不能在批处理时加-quit,因此要在工程完成时手动调用一下EditorApplication.Exit(errorCode);
同时不建议在主线程做这种阻塞的等待,可能会导致一些回调无法执行而卡死。