[Unity3D经验分享]批处理工具 (提前下班神器)

Unity中批处理的原理与使用

前言

由于从事工业三维可视化的原因,我们的项目中有大量的模型需要在Unity中打包为assetbundle文件,其实打包assetbundle的过程是很机械的过程,这种重复性很高变动很小的工作我们通常应该想到使用BATCH(批处理脚本/批处理文件)来解决这个问题,下面我们根据实际的项目来感受一下批处理程序的魅力。

主要内容

  • 批处理工具原理
  • 如何使用/何种情况使用(使用案例)

使用原理

  • 原理: 使用批处理程序来调用已经编写好的Unity拓展方法。

接下来看一下如何编写UnityEditor方法和BATCH是如何调用UnityEditor方法的。

什么是UnityEditor拓展?

放在工程目录下Assets/Editor文件下的方法都是对Unity引擎编辑器的拓展,一般常见的插件都会编写一部分编辑器拓展代码来自定义插件的Inspector面板等其他操作。

怎么利用批处理来触发编辑器的方法,Editor目录下的方法有多种方式来触发

  • 利用自定义的按钮来触发;

这里写图片描述

这里写图片描述

using UnityEditor;

public class MyClass
{
    [MenuItem("My Tools/MyFunc1")]
    private static void MyFunc1()
    {
        //..你的操作
    }
}
  • 自定义窗口中来调用

这里写图片描述

using UnityEditor;
using UnityEngine;

public class MyClass : EditorWindow
{
    // 重写window面板
    private void OnGUI()
    {
        if(GUILayout.Button("MyFunc1"))
        {
            MyFunc1();
        }
    }

    // 打开窗口
    [MenuItem("My Tools/My Window")]
    private static void OpenMyWindow()
    {
        GetWindow<MyClass> (true, "My Window");
    }

    [MenuItem("My Tools/MyFunc1")]
    private static void MyFunc1()
    {
        //..你的操作
        Debug.Log ("你的操作");
    }
}
  • 利用批处理来调用

这里写图片描述

using UnityEditor;

public class MyWindow : EditorWindow
{
    public static void MyFunc1()
    {
        //..你的操作
        Debug.Log("你的操作");
    }
}
rem 发布工具
@echo off
echo 启动 Unity.exe 请稍后...
start /min D:\Unity\Editor\Unity.exe -batchmode -projectPath D:\MyProject\BatchProject -executeMethod MyClass.MyFunc1
Pause
taskkill /f /im unity.exe
  • 执行结果
  • Eidtor日志路径Win7在C:\Users\Administrator\AppData\Local\Unity\Editor\Editor.Log
    这里写图片描述

  • echo 为DOS编程中一种显示消息的方法

  • start DOS编程中用于启动应用程序的命令
  • -batchmode 是Unity提供的Command line arguments中较为常用的一种,它是后台运行Unity,不显示Unity界面,这对于把机械的工作交给策划?美术?是极其重要的。
    在-batchmode下运行Unity。这应该始终与其他命令行参数一起使用,因为它确保没有出现弹出窗口,并且不需要任何人为干预。执行脚本代码期间发生异常时,资产服务器更新失败或其他失败的操作,Unity立即退出并返回代码1。
    请注意,在批处理模式下,Unity将其日志输出的最小版本发送到控制台。但是,日志文件仍然包含完整的日志信息。在编辑器打开相同的项目时以批处理模式打开项目不受支持; Unity的一个实例只能一次运行。

  • -projectPath 指定项目的路径

  • -executeMethod(ClassName.MethodName) 调用Unity编辑器某个类型中的某个方法

  • 一旦Unity启动,项目打开,并且执行了可选的Asset Server更新之后,执行静态方法。这可以用于执行持续集成,执行单元测试,构建或准备数据等任务。要从命令行进程返回错误,请抛出异常,导致Unity退出代码1,或者使用非零返回代码调用EditorApplication.Exit。要传递参数,将它们添加到命令行并使用函数检索它们System.Environment.GetCommandLineArgs。要使用-executeMethod,您需要将封闭的脚本放在编辑器文件夹中。要执行的方法必须定义为static。

  • 更多Unity Command line arguments,最新Unity支持直接用.bat脚本直接导出linux、MacOS、Window的应用,暂时不支持Android和IOS等其它终端的输出。

  • 更多DOS Command line arguments,DOS命令行不许要去专门当做一门语言学习,你只需要根据自己的需求百度一下命令行的使用方式即可。

使用案例

批处理打包assetbundle

  • 1.点击.bat文件之后的界面
    这里写图片描述
  • 2.等待启动资源导入选择导出路径的界面
    这里写图片描述
    -3.选择导出路径
    这里写图片描述
    -4.等待生成结果,并按下任意键退出,自动从清除进程中的Unity.exe
    这里写图片描述

  • 编辑器代码

public class MyClass : EditorWindow
{
    // 重写window面板
    private void OnGUI()
    {
        if ( GUILayout.Button("选择路径并导出资源文件") )
        {
            string savePath = EditorUtility.SaveFolderPanel("导出路径" , "" , "");
            Build(savePath);
        }
    }

    private static string _modelName = null;

    [MenuItem("My Tools/Quickly Build")]
    public static void QuicklyBuild()
    {
        GetWindow<MyClass>(true , "打包工具");
        string assetPath = EditorUtility.OpenFolderPanel("选择资源路径" , "" , "");
        if (!Directory.Exists(Application.dataPath + "Resources/Models"))
            Directory.CreateDirectory(Application.dataPath + "Resources/Models");
        Copy(assetPath , Application.dataPath + "/Resources/Models");
        GetModelName();
    }

    // 自动选取后缀为.fbx的模型命名
    private static void GetModelName()
    {
        DirectoryInfo info = new DirectoryInfo(Application.dataPath + "/Resources/Models");
        foreach ( FileInfo file in info.GetFiles() )
            if ( file.Extension == ".FBX" )
                _modelName = file.Name.Replace(".FBX" , "");
    }

    // 打包资源
    public static void Build(string savePath)
    {
        Debug.Log(_modelName);
        GameObject model = Resources.Load<GameObject>("Models/" + _modelName);
        Object oldPrefab = PrefabUtility.CreateEmptyPrefab("Assets/Resources/" + model.name + ".prefab");
        GameObject newPrefab = PrefabUtility.ReplacePrefab(model , oldPrefab);
        Caching.CleanCache();
        string modelName = newPrefab.name;
        string assetBundlePath = savePath + "/" + modelName + ".assetbundle";
        if ( BuildPipeline.BuildAssetBundle(newPrefab , null , assetBundlePath , BuildAssetBundleOptions.CollectDependencies) )
            Debug.Log(modelName + "资源打包成功");
        AssetDatabase.Refresh();
        Delete();
    }

    // 清空文件夹
    public static void Delete( )
    {
        DirectoryInfo info = new DirectoryInfo(Application.dataPath + "/Resources/Models");
        info.Delete(true);
    }

    // 文件导入
    public static void Copy( string sPath , string dPath )
    {
        DirectoryInfo info = new DirectoryInfo(sPath);
        foreach ( DirectoryInfo directory in info.GetDirectories() )
        {
            if ( !Directory.Exists(dPath + "/" + directory.Name) )
            {
                Directory.CreateDirectory(dPath + "/" + directory.Name);
            }
            foreach ( FileInfo file in directory.GetFiles() )
            {
                if ( !File.Exists(dPath + "/" + directory.Name + "/" + file.Name) )
                {
                    File.Copy(sPath + "/" + directory.Name + "/" + file.Name , dPath + "/" + directory.Name + "/" + file.Name);
                }
            }
        }
        foreach ( FileInfo file in info.GetFiles() )
        {
            if ( !File.Exists(dPath + "/" + file.Name) )
            {
                File.Copy(sPath + "/" + file.Name , dPath + "/" + file.Name);
            }
        }
    }
}
  • 批处理代码(这个文件我是放在桌面的,使用时需要自己配置)
rem 我的打包工具
@echo off
echo 启动 Unity.exe 请稍后...
echo 清理缓存
rd /s /q "D:\UnityProjects_4.6\HYProjects\HYPTProject\Assets\Resources\Models"
echo 新建目录
md "D:\UnityProjects_4.6\HYProjects\HYPTProject\Assets\Resources\Models"
echo 开始操作
start /min D:\Unity\Editor\Unity.exe -batchmode -projectPath D:\MyProject\BatchProject -executeMethod MyClass.QuicklyBuild
echo 操作完成,按任意键退出...
Pause
taskkill /f /im unity.exe

明白原理之后,操作起来还是很简单的,这里提供一个例子给大家,大家也可在自己的项目中参考实现一下。具体的DOS命令我就不讲解了。百度一下,你就知道

批处理处理模型

原理同上

批处理build多平台发布包

新版Unity已经提供了命令行来Build Lunix、MacOS、Windows平台的发布包

后续拓展

  • 批处理工具基本在任何操作重复的情况都可以使用,只需要将操作的步骤封装为方法,让代码去执行即可。
  • 批处理是一种操作思想,任何可以不需要你动手的事情你都可以编写为一个工具让不懂操作的其他人来替你完成。这样你就可以“提前下班啦”。

UGUI组件系列

Unity框架解读系列

分享地址(置顶目录包含所有组件的最新下载地址)

猜你喜欢

转载自blog.csdn.net/qq_29579137/article/details/76598929