携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第25天,点击查看活动详情
Unity端C#打包代码框架
Unity端的打包系统包含的内容上一篇已经说了,简单来说,本质上是要调用BuildPlayer去打版本包。而为了实现这个最终目的,需要获取打包参数进行各种准备工作。因此C#打包脚本大概可以分成几个部分:
- 打包参数类定义
- 命令行解析和打包参数获取
- 根据打包参数修改代码预处理定义,选择不同的资源和不同的Unity场景
- 执行打包并进行后续处理
打包参数类定义
为了自定义,我们需要设置打包参数,因此有必要将所有的参数定义在一个类里面,方便参数的构造和传递。这儿给一个例子:
namespace CustomBuilder
{
public enum BuildOS
{
Windows,
Mac,
iOS,
Android
}
public enum BuildStore
{
Default,
Steam,
Google,
Apple
}
public class BuildConfig
{
public string AppName = "AppName";
public BuildOS OS = BuildOS.Windows;
public BuildStore Store = BuildStore.Default;
public string VersionBase = "0.1.0";
public int SvnReversion = 1;
//for filename and path
public string VersionType = "Beta";
public string BuildDateTime = null;
public string OutputFolder = null;
//for compile
public bool DevelopmentMode = false;
public string[] BuildScenes = null;
}
}
BuildConfig类中的成员就是需要设置的打包参数,这个是根据业务需求进行定义的。我这儿给出了一些常用的参数。
命令行参数解析和参数获取
打包的第一步就是获取命令行参数,以及打包参数。在我们的系统中,我们只获取一个命令行参数,这个参数就是包含所有打包参数的json文件,然后解析这个文件获取到打包参数。我们使用一个单独的类去做这个工作:
using UnityEngine;
using CustomBuilder;
using System.IO;
using System;
public class BuilderCommandline
{
public static void Build_SwitchEnv()
{
var config = LoadBuildConfigFromJson(ParseCommandLine());
MainBuilder.Config = config;
MainBuilder.Build_SwitchEnv();
}
public static void Build_MakePackage()
{
var config = LoadBuildConfigFromJson(ParseCommandLine());
MainBuilder.Config = config;
MainBuilder.Build_MakePackage();
}
static string ParseCommandLine()
{
string configFilePath = null;
string[] strs = System.Environment.GetCommandLineArgs();
foreach (var s in strs)
{
if (s.Contains("-configFilePath:"))
{
int sidx = s.IndexOf(":");
if (sidx >= 0)
{
string arg = s.Substring(sidx + 1);
configFilePath = arg;
}
}
}
return configFilePath;
}
public static BuildConfig LoadBuildConfigFromJson(string jsonPath)
{
BuildConfig config = default;
if(File.Exists(jsonPath))
{
try{
string dataRead = "";
using(FileStream stream = new FileStream(jsonPath, FileMode.Open))
{
using(StreamReader reader = new StreamReader(stream))
{
dataRead = reader.ReadToEnd();
}
}
config = JsonUtility.FromJson<BuildConfig>(dataRead);
}
catch(Exception e)
{
Debug.LogError($"Failed to load build config from file {jsonPath}. Exception:{e}");
}
}
return config;
}
}
该类是和Unity命令行交互的接口,它包含两个打包方法:Build_SwitchEnv和Build_MakePackage。因为我们在打包过程中要修改程序的预编译定义,这会导致Domain Reload,如果没有reload完成就直接执行BuildPlayer会有一定的几率造成打出的版本crash。这个在Unity论坛上有相关的讨论:forum.unity.com/threads/lev… 因此这儿使用两个独立的打包方法,分别使用Unity命令行执行。如果打包过程中需要执行Addressable build,那么还需一个独立的打包方法用于Make Addressable。
解析命令行参数
详见代码中的ParseCommandLine方法,这儿我们只需要解析一个参数configFilePath。
解析Json文件
详见代码中的LoadBuildConfigFromJson方法。使用FileStream打开文件,使用StreamReader读取,之后使用JsonUtility.FromJson<BuildConfig>(dataRead);方法直接从Json数据中解析出我们上面定义的BuildConfig类。
调用实际的打包方法
以Build_SwitchEnv为例,将解析出的Config对象设置为MainBuilder的当前使用的Config,并且调用MainBuilder.Build_SwitchEnv()进行实际的操作。MainBuilder是我们的核心打包类,会根据设置的参数,根据游戏的实际业务逻辑对代码和资源进行处理。Build_SwitchEnv是根据当前的OS和Store等参数切换代码的环境,也就是设置不同的预编译定义。
小结
本篇中我们首先介绍了C#端的打包代码的结构,并详细说明了打包参数的定义,打包命令行参数的获取和打包参数的解析,并给出一个实际的例子。下篇中我们讲实际分析最重要的核心打包类MainBuilder。