0. 热更新做什么
1、资源
热更资源和热更步骤(Bundle)
2、代码
Lua与C#的交互(xLua)
3、框架开发流程
第一阶段 :Bundle处理
构建;加载;更新
第二阶段 :C#调用Lua
Lua加载与管理
Lua绑定与执行
第三阶段 :向Lua提供接口
第四阶段:完善与优化
1. 资源目录划分
2. BundleBuildTool
2.1 AssetBundle & AssetBundleBuild
2.2 Bundle Build
查找BuildResources下的资源文件
使用Unity提供发BuildPipeline进行构建
注意:meta不需要打入Bundle
2.3 Bundle Build策略
按文件夹打包 :最底层文件夹
优势:bundle数量少,小包模式:首次下载快
劣势:后期更新补丁大
按文件打包 :每个文件单独打包
优势:后期更新补丁小
劣势:bundle数量多,小包模式:首次下载稍慢
2.4 程序实现
工具类
PathUtil:用于路径处理
路径字段
项目Assets完整路径;
等待打包的资源路径;
AssetBundle输出路径;
AssetBundle资源路径;
处理路径方法
获取文件相对Unity/Assets文件夹的相对路径;
获取标准化路径;
获取各类资源的路径;
cs
public class PathUtil
{
//项目中Assets文件夹的完整路径
public static readonly string AssetPath = Application.dataPath;
//需要打Bundle的目录
public static readonly string BuildResourcesPath = AssetPath + "/BuildResources/";
//Bundle输出目录
public static readonly string BundleOutPath = Application.streamingAssetsPath;
/// <summary>
/// 获取Unity的相对路径
/// </summary>
/// <param name="path">文件或文件夹的完整路径</param>
/// <returns>相对于Assets文件夹的路径</returns>
public static string GetUnityPath(string path)
{
if (string.IsNullOrEmpty(path)) return string.Empty;
return path.Substring(path.IndexOf("Assets"));
}
/// <summary>
/// 获取标准路径
/// </summary>
/// <param name="path">文件或文件夹的路径</param>
/// <returns>将反斜杠替换为正斜杠的标准化路径</returns>
public static string GetStandardPath(string path)
{
if (string.IsNullOrEmpty(path))
return string.Empty;
return path.Trim().Replace("\\", "/");
}
}
BuildTool
在 Unity 编辑器中构建 AssetBundles
cs
public class BuildTool : Editor
{
[MenuItem("Tools/Build Bundle/Windows")]
static void BundleWindowsBuild()
{
Build(BuildTarget.StandaloneWindows);
}
[MenuItem("Tools/Build Bundle/Android")]
static void BundleAndroidBuild()
{
Build(BuildTarget.Android);
}
[MenuItem("Tools/Build Bundle/iOS")]
static void BundleiOSBuild()
{
Build(BuildTarget.iOS);
}
static void Build(BuildTarget target)
{
//创建AssetBundleBuild打包列表
List<AssetBundleBuild> assetBundleBuilds = new List<AssetBundleBuild>();
//填充列表
string[] files = Directory.GetFiles(PathUtil.BuildResourcesPath, "*", SearchOption.AllDirectories); //获取BuildResourcesPath目录下所有文件
for (int i = 0; i < files.Length; i++) //根据文件构建AssetBundleBuild对象
{
//跳过meta文件
if (files[i].EndsWith(".meta"))
continue;
//处理要打包的文件,根据BundleResources中文件创建AssetBundleBuild对象
AssetBundleBuild assetBundle = new AssetBundleBuild(); //创建一个新的AssetBundleBuild对象
string fileName = PathUtil.GetStandardPath(files[i]); //获取标准化后的文件路径
Debug.Log("files:" + fileName); //Log
string assetName = PathUtil.GetUnityPath(fileName); //获取相对于Assets文件夹的路径
assetBundle.assetNames = new string[] { assetName }; //设置assetBundle的资源名称
string bundleName = fileName.Replace(PathUtil.BuildResourcesPath, "").ToLower();
assetBundle.assetBundleName = bundleName + ".ab"; //设置assetBundle的名称
//将AssetBundleBuild对象加入打包列表
assetBundleBuilds.Add(assetBundle);
}
//检查并初始化输出文件夹
if (Directory.Exists(PathUtil.BundleOutPath))
Directory.Delete(PathUtil.BundleOutPath, true);
Directory.CreateDirectory(PathUtil.BundleOutPath);
//构建AssetBundles
BuildPipeline.BuildAssetBundles(PathUtil.BundleOutPath, assetBundleBuilds.ToArray(), BuildAssetBundleOptions.None, target);
}
}
3 BuildTool 完善
3.1 在Unity中动态加载资源
3.2 完善bundlle
获取和打包依赖项,生成版本文件
版本文件:
版本号:1.0.1
文件信息:文件路径名 | bundle名 | 依赖文件列表
获取依赖文件方法
使用AssetDatabase.GetDependencies获取指定资源的依赖项存储在files数组中
使用LINQ查询过滤files数组,去除脚本文件和指定文件自身
cs
/// <summary>
/// 获取依赖文件列表
/// </summary>
/// <param name="curFile"></param>
/// <returns></returns>
static List<string> GetDependence(string curFile)
{
List<string> dependence = new List<string>();
string[] files = AssetDatabase.GetDependencies(curFile);
dependence = files.Where(file => !file.EndsWith(".cs") && !file.Equals(curFile)).ToList();
return dependence;
}
Build方法循环体中增加
cs
//添加该对象依赖信息
List<string> dependenceInfo = GetDependence(assetName);
string bundleInfo = assetName + "|" + bundleName + ".ab";
if (dependenceInfo.Count > 0)
bundleInfo = bundleInfo + "|" + string.Join("|", dependenceInfo);
bundleInfos.Add(bundleInfo);
Build方法增加生成版本文件
cs
//构建AssetBundles
BuildPipeline.BuildAssetBundles(PathUtil.BundleOutPath, assetBundleBuilds.ToArray(), BuildAssetBundleOptions.None, target);
File.WriteAllLines(PathUtil.BundleOutPath + "/" + AppConst.FileListName, bundleInfos);
AssetDatabase.Refresh();
版本文件belike
cs
Assets/BuildResources/UI/Prefab/testUI.prefab|ui/prefab/testui.prefab.ab|Assets/BuildResources/UI/Res/background.png|Assets/BuildResources/UI/Res/button_150.png
Assets/BuildResources/UI/Res/background.png|ui/res/background.png.ab
Assets/BuildResources/UI/Res/button_150.png|ui/res/button_150.png.ab
Assets/BuildResources/UI/Res/radio_100.png|ui/res/radio_100.png.ab
Assets/BuildResources/UI/Res/slider_handle.png|ui/res/slider_handle.png.ab
Assets/BuildResources/UI/Res/universal_panel_40.png|ui/res/universal_panel_40.png.ab