Unity构建详解(10)——Unity构建流程

【前言】

我们知道从源代码到可执行文件有四个步骤:预编译、编译、汇编、链接

  • 预编译:处理源代码文件中的以"#"开始的各种预编译指令
  • 编译:通过语法语义分析等将源代码文件转为中间语言文件并进行优化,再生成汇编代码文件
  • 汇编:将汇编代码文件翻译成机器指令格式的二进制文件,即生成目标文件
  • 链接:将多个目标文件链接起来生成可执行文件

Unity本身不会去构建出来一个可执行文件,最终的构建流程还是依托与不同平台的构建工具,Unity的构建相当于为平台构建工具提供数据,这些数据只要是三类:代码文件、资源文件、配置文件。例如,构建出Apk最终还是需要调用Android SDK和NDK,构建出IPA最终还是要在Xcode中进行的。

一般来说,构建会在软件上提供交互入口,点击后开始自动构建,这种方式用的是软件提供的自动构建流程。

我们会有自定义构建处理的需求,在整个构建流程中会提供Hook让我们在代码中去做自定义处理。一般有三种方式:

  • 提前注册
  • 继承接口
  • 使用特性

【Unity构建流程】

构建流程为:准备构建->资源收集->脚本编译->Shader编译->配置文件生成->平台构建

1.发起构建:调用BuildPipeline.BuildPlayer(buildPlayerOptions)发起构建,buildPlayerOptions内容如下:

  • string[] scenes 要构建的场景的路径
  • string locationPathName 输出路径
  • string assetBundleManifestPath
  • BuildTargetGroup targetGroup
  • BuildTarget target
  • int subtarget
  • BuildOptions options
  • string[] extraScriptingDefines

2.平台切换:发出回调OnActiveBuildTargetChanged,继承自IActiveBuildTargetChanged。一般来说会事先切换好。

3.准备构建:引擎先调用PrepareForBuild,其继承自BuildPlayerProcessor

在这一步,我们需要事先把需要的资源文件和配置文件准备好。Unity构建时会从Plugins和StreamingAssets文件中收集资源,构建前先将需要放入初始包的资源放入这两个文件夹中。

由于Unity认为文件夹中的所有文件都是需要收集的,这里会存在两个问题:文件夹中的某些资源在打开时不需要,需要的一些资源不在文件夹中。

存在不需要的资源是因为项目管理没做好,需要事先规定并坚持执行:不进包的资源不能放在改文件夹中。否则,出现该问题会导致初始包包体增大。如果已经出现该问题,那么积重难返,需要在构建前删掉不需要的资源。

针对不在资源中的文件夹,需要从其他地方Copy过来,例如有些Bundle要进初始包,但打包出来的Bundle在其他路径,不在StreamingAssets文件夹中;有些插件不在事先放到Plugins文件夹中也要Copy过来。

4.资源收集

5.准备完成:引擎OnPreprocessBuild,继承自IPreprocessBuildWithReport

6.编译脚本:

C#脚本经过C#编译器生成Dll,引擎调用OnPostBuildPlayerScriptDLLs,其继承自IPostBuildPlayerScriptDLLs。一般来说承载游戏逻辑的C#脚本会被编译成Assembly.Csharp.dll,Plugins文件夹中的被编译成Assembly-CSharp-firstpass.dll。可以在编译完成后做自定义处理,但这会拖慢构建速度,一般不处理。

生成Dll后UnityLinker.exe会对代码进行裁剪,裁剪前发出GenerateAdditionalLinkXmlFile,其继承自 IUnityLinkerProcessor。生成自定义的Link.xml文件用于代码剥离,可以用来优化项目构建大小,减少不必要的代码和资源,提高项目的性能和加载速度

IL2CPP对剥离后的代码进行编译,生成二进制的代码文件。

7.编译Shader

编译某个Shader前,引擎调用OnProcessShader,其继承自IPreprocessShaders

编译某个ComputeShader 前,引擎调用OnProcessComputeShader,继承自IPreprocessComputeShaders

8.构建完成:调用OnPostprocessBuild,需要继承IPostprocessBuildWithReport。对应的特性为PostProcessBuildAttribute

如果是iOS平台,这时已经生成了XCode工程,通过BuildReport.Summary.OutputPath可以知道工程路径,可以将一些ios的库拷贝到xcode工程中。如果做自动化构建,需要在代码中修改xcode工程的属性和配置。

如果需要导出Android工程,在Android Gradle工程生成后,引擎会调用OnPostGenerateGradleAndroidProject,其继承自IPostGenerateGradleAndroidProject

9.平台构建

构建APK会调用Android SDK 和NDK自动构建

构建IPA需要在Xcode工程中构建

相关推荐
垂葛酒肝汤7 小时前
Unity中的协程的原理
unity·游戏引擎
垂葛酒肝汤9 小时前
Unity第一个项目
unity·游戏引擎
Sator19 小时前
Unity的InputSystem常见问题和疑惑解答
java·unity·游戏引擎
郝学胜-神的一滴9 小时前
QtOpenGL多线程渲染方案深度解析
c++·qt·unity·游戏引擎·godot·图形渲染·unreal engine
__water1 天前
RHK《Unity接入PicoSDK入门》
unity·游戏引擎·picosdk
我的golang之路果然有问题1 天前
unity 资源导入 godot
unity·游戏引擎·godot
迪普阳光开朗很健康1 天前
Unity+Vscode+EmmyLua+XLua 调试实战
vscode·unity·游戏引擎
Var_al1 天前
Unity编辑器扩展:标准化UI组件快速创建工具开发指南
ui·unity·c#·编辑器
CreasyChan1 天前
Unity 中的 IEnumerator协程详解
unity·c#·游戏引擎
熬夜敲代码的小N1 天前
基于Unity开发Pico VR眼镜基础应用:从环境搭建到实战部署全解析
人工智能·unity·游戏引擎·vr