本篇知识来源于unity官方手册以及siki学院的相关教程,链接如下,仅作学习分享
AssetBundle(创建打包)入门学习(基于Unity2017) - SiKi学院|SiKi学堂 - unity|u3d|虚幻|ue4/5|java|python|人工智能|视频教程|在线课程
目录
0.热更新是什么
1.AssetBundle是什么
2.流程分析
游戏运行时
AssetBundle本身
编辑器下
3.工作流程一览
0标记AB包对象
1.构建(上传)AssetBundle
编辑
关于上传服务端
2.从服务器加载AssetBundle
3.从本地加载AssetBundle
4.卸载AssetBundle
4.必须知道的啸规则
打包压缩选项
依赖打包
目的
原理
加载依赖
关于完整性和安全性
5.究极杀器
旧版轻量化可视化AB包工具
新版极致方便AB包的再封装工具Addressables
0.热更新是什么
一言蔽之 就是你玩游戏的时候仍旧能下载资源,不需要把整个游戏重新下载 -安装 -打开
常见于网络游戏更新,DLC等
1.AssetBundle是什么
AssetBundle是Unity提供的热更新方案
表现形式上是一个存档文件,包含可在运行时由 Unity 加载的特定于平台的非代码资源(比如模型、纹理、预制件、音频剪辑甚至整个场景)
AssetBundle - Unity 手册 ,其本质就是一个文件夹(或者压缩包),用来存储/加载重要资源
其包含了有两类文件
序列化文件
源文件
2.抽象流程分析
游戏运行时
- 加载 AssetBundle:从文件或服务器加载 AssetBundle
- 加载 Asset:从 AssetBundle 中加载具体的资源
- 卸载 AssetBundle 和 Asset:使用完资源后,卸载 AssetBundle 和资源以释放内存
AssetBundle本身
- AssetBundle:包含打包的资源文件
- manifest:包含 AssetBundle 的元数据,用于管理依赖关系和版本控制
编辑器下
- 直接加载资源路径下的资源文件:在编辑器模式下,直接从资源路径加载资源文件
- AssetDatabase 加载 Asset:使用 AssetDatabase API 加载资源
- StreamingAssets 文件夹下的资源文件不做处理直接使用:StreamingAssets 文件夹中的资源文件在运行时直接使用,无需打包
3.工作流程一览
0标记AB包对象
例如我将一个cube和一个sphere放到了prefab文件夹下,其inspector最下面会有如下选项
第一个None其实就是AB包的包名,其可以分类用斜线分割开
第二个None就是该包的后缀名,没错 指定任意后缀名
1.构建(上传)AssetBundle
将此脚本放到Editor文件夹下
2022.3版本 BuildAssetBundle方法已经弃用了,建议用加s的方法或者官网查询
using UnityEditor;
public class AB包
{
[MenuItem("AB包/上传")]
public static void UpAB(){
BuildPipeline.BuildAssetBundles("Assets/AssetBundles",
BuildAssetBundleOptions.None,
BuildTarget.StandaloneWindows);
}
}
三个参数分别是 输出路径, 打包选项 , 打包平台
a包 /方块后缀名 之中包含了Cube这个么一个物体,你可以将更多的物体放到这个包之中
b包同理
关于上传服务端
怎么上传到网络端,需要移步网络知识处,我日后会在这里补充链接
保存到本地就非常简单了 [MenuItem("AB包/上传")]特性会执行构建并保存的静态方法
2.从服务器加载AssetBundle
StartCoroutine(LoadAB());
}
IEnumerator LoadAB(){
string uri = @"http://localhost/AssetBundles/cubewall.unity3d";
UnityWebRequest www = UnityWebRequestAssetBundle.GetAssetBundle(uri);
yield return www.SendWebRequest();
AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(www);
if(bundle!=null)
Instantiate(bundle.LoadAsset<GameObject>("CubeWall"));
}
代码进行了如下步骤:
创建请求:使用 UnityWebRequestAssetBundle.GetAssetBundle(url)
创建一个请求对象
发送请求:使用 SendWebRequest
方法发送请求并等待响应
检查结果:检查请求结果,如果成功,使用 DownloadHandlerAssetBundle.GetContent
获取 AssetBundle
加载资源:使用 LoadAsset
方法从 AssetBundle 中加载资源并实例化
3.从本地加载AssetBundle
注意!要是绝对路径还好说,相对路径需要完整路径,也就是说后缀名也要加进来
本地同步加载
// Start is called before the first frame update
void Start()
{
string path = "Assets/AssetBundles/a包/方块.后缀名";
AssetBundle asset = AssetBundle.LoadFromFile(path);
if(asset!=null){
Instantiate( asset.LoadAsset<GameObject>("Cube"));
}
}
本地异步加载,我直接改了Start函数,仅供参考
只需要知道Ienumerator ,yield return 和 AssetBundleCreateRequest ,LoadFromFileAsync方法配合即可
using UnityEngine;
using System.Collections;
public class LoadAssetBundleAsync : MonoBehaviour
{
// Start is called before the first frame update
IEnumerator Start()
{
string path = "Assets/AssetBundles/a包/方块.后缀名";
AssetBundleCreateRequest bundleRequest = AssetBundle.LoadFromFileAsync(path);
yield return bundleRequest;
AssetBundle assetBundle = bundleRequest.assetBundle;
if (assetBundle != null)
{
AssetBundleRequest assetRequest = assetBundle.LoadAssetAsync<GameObject>("Cube");
yield return assetRequest;
GameObject prefab = assetRequest.asset as GameObject;
Instantiate(prefab);
assetBundle.Unload(false);
}
}
}
4.卸载AssetBundle
// 卸载 AssetBundle 但保留已加载的资源
// 参数未true时将会卸载所有资源
assetBundle.Unload(false);
// 卸载未使用的资源
Resources.UnloadUnusedAssets();
4.必须知道的啸规则
打包压缩选项
Unity - 脚本 API: BuildAssetBundleOptions - Unity 文档
其实就是一些压缩算法或者不压缩处理
依赖打包
目的
比如我上述的a包中的方块和b包的求 如果都加载了同一个材质
那么我为了将打包出去的资源进行大小优化,就会单独将创建一个c包里面放该材质
这就叫做依赖打包
原理
但是,加载的时候我怎么知道哪个是被依赖的包呢?
请看下图:
每一个AB包中都会有AssetBundles.manifest文件
其中在Info_n下会有Dependence,其中就是依赖包
你只需要将依赖和被依赖包加载出来,unity将会通过自动处理该依赖关系
加载依赖
首先来看看没有加载依赖包的情况
即使你本地有该材质也不行,因为AB包就是走AB包的路径,和本地没有关系
using UnityEngine;
public class LoadFromAB : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
string[] bundlePath ={
"Assets/AssetBundles/a包/方块.后缀名",
"Assets/AssetBundles/b包/球.后缀名",
"Assets/AssetBundles/c包/材质.后缀名"
};
AssetBundle assets1 = AssetBundle.LoadFromFile(bundlePath[0]);
Instantiate(assets1.LoadAsset<GameObject>("Cube"));
AssetBundle assets2 = AssetBundle.LoadFromFile(bundlePath[1]);
Instantiate(assets2.LoadAsset<GameObject>("Sphere"));
}
}
添加一句加载依赖包的代码
AssetBundle assets = AssetBundle.LoadFromFile(bundlePath[3]);
很有精神
关于完整性和安全性
AssetBundle 下载的完整性和安全性 - Unity 手册
生成 CRC 校验和: 在构建 AssetBundle 时,Unity 会生成一个 32 位的 CRC 校验和,并记录在
.manifest
文件中。你可以使用BuildPipeline.GetCRCForAssetBundle
方法来获取这个校验和下载和校验 AssetBundle: 使用
UnityWebRequestAssetBundle.GetAssetBundle
方法下载 AssetBundle 时,可以传入预期的 CRC 值进行校验。如果下载的 AssetBundle 的 CRC 与预期值不匹配,则不会加载该 AssetBundle
5.究极杀器
旧版轻量化可视化AB包工具
Unity-Technologies/AssetBundles-Browser: Editor tool for viewing and debugging asset bundle contents before and after builds
但是我不去做介绍,因为官方已经停止更新了,取而代之......
新版极致方便 自动管理AB包的再封装工具Addressables
【游戏开发探究】Unity Addressables资源管理方式用起来太爽了,资源打包、加载、热更变得如此轻松(Addressable Asset System | 简称AA)_unity aa-CSDN博客
Addressables 软件包 |Addressables 可寻址 |2.3.1
我会更新此工具的文章,来日方长