之前关于AssetBundle的两个博客:
https://blog.csdn.net/wodownload2/article/details/80226435
https://blog.csdn.net/wodownload2/article/details/80313859
参考网址:https://docs.unity3d.com/Manual/AssetBundles-Native.html
https://blog.csdn.net/ithot/article/details/75128535 这个网址,可以给每个资源自动命名assetbundle的名称和后缀,无需手动指定。
本节再次提起这个知识点。
1、打包
创建三个资源,一个cube,一个sphere,一个是材质。
打包代码:
using UnityEditor;
using System.IO;
public class BuildAssetBundle
{
[MenuItem("Asset/BuildAssetBundle")]
static void BuildBundle()
{
string outPath = "Bundles";
if(!Directory.Exists(outPath))
{
Directory.CreateDirectory(outPath);
}
BuildPipeline.BuildAssetBundles(outPath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
}
}
分别给cube配置路径:
给sphere配置路径:
给材质配置路径:
打包之后:
文件夹解释:
material为材质打包之后放的位置
prefab为cube和sphere打包之后放的位置
bundles为manifest的打包文件;
bundles.manifest为供程序员查看的文件,可以看看各个bundles的依赖关系。
2、加载
首先加载清单文件:
AssetBundle ab1 = AssetBundle.LoadFromFile("Bundles/Bundles");
AssetBundleManifest manifest = ab1.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
3、获取依赖并加载依赖包
string[] dependencies = manifest.GetAllDependencies("prefab/cube.bundle");
foreach (string dependency in dependencies)
{
Debug.LogError(dependency);
AssetBundle depend = AssetBundle.LoadFromFile("Bundles/" + dependency);
}
4、实例化资源
AssetBundle ab = AssetBundle.LoadFromFile("Bundles/prefab/cube.bundle");
GameObject cube = ab.LoadAsset<GameObject>("Cube");
Instantiate(cube);
5、卸载ab镜像文件
首先改bundle变量为类成员,然后一个一个卸载
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LoadBundle : MonoBehaviour
{
private AssetBundle manifesetBundle;
private AssetBundle materialBundle;
private AssetBundle cubeBundle;
void Start ()
{
//1.加载清单bundle
manifesetBundle = AssetBundle.LoadFromFile("Bundles/Bundles");
manifesetBundle.name = "ManifesetBundle";
AssetBundleManifest manifest = manifesetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
string[] dependencies = manifest.GetAllDependencies("prefab/cube.bundle"); //Pass the name of the bundle you want the dependencies for.
foreach (string dependency in dependencies)
{
Debug.LogError(dependency);
//2.加载材质bundle
materialBundle = AssetBundle.LoadFromFile("Bundles/" + dependency);
}
//3.加载立方体bundle
cubeBundle = AssetBundle.LoadFromFile("Bundles/prefab/cube.bundle");
GameObject cube = cubeBundle.LoadAsset<GameObject>("Cube");
Instantiate(cube);
}
public void Update()
{
if(Input.GetKeyDown(KeyCode.A))
{
manifesetBundle.Unload(false);
}
if (Input.GetKeyDown(KeyCode.B))
{
materialBundle.Unload(false);
}
if (Input.GetKeyDown(KeyCode.C))
{
cubeBundle.Unload(false);
}
}
}
观察过程:
此时有三个bundle:
清单bundle,这个我们显示的程序中赋值了一个名字;
prefab/cube.bundle
material/red.bundle
按住A键,则会减少清单bundle;
按住B键,则会减少prefab/cube.bundle
按住C键,则会减少material/red.bundle
记得没按一个键,需要重新采样帧才能观察到效果。
以上是unload(false)的情况。
如果改为unload(true),
if (Input.GetKeyDown(KeyCode.B))
{
materialBundle.Unload(true);
}
则其cube的立方体材质丢失。
观察:
说明:unload(true),连同镜像文件和asset都去除掉了。
6、依赖关系
如上图所示,我们的prefab使用了材质,Material,材质有shader、shader有贴图
也就是prefab依赖于三个资源,如果我们把三个资源分别打包。
material文件夹下存放的是:材质球bundle
prefab文件夹下存放的是:cube和sphere的bundle
shader文件夹下存放的是:shader代码的bundle
textrue文件夹下存放的是:贴图资源bundle
使用上面的加载并实例化的方法,对于加载:
string[] dependencies = manifest.GetAllDependencies("prefab/cube.bundle");
foreach (string dependency in dependencies)
{
Debug.LogError(dependency);
//2.加载材质bundle
materialBundle = AssetBundle.LoadFromFile("Bundles/" + dependency);
}
加载的是cube.bundle,我们看到其依赖是:
它只依赖了material.bundle。
但是通过代码是得到了所有的依赖,所以输出的是:
共计三个依赖:
也就是通过这句代码:
string[] dependencies = manifest.GetAllDependencies("prefab/cube.bundle");
unity会自动为我们返回所有的依赖包,包括它依赖的依赖,会递归查询,最终返回总的依赖包。
这样就很方便后续的加载了。
总结:
1、如果我们使用方法:
BuildPipeline.BuildAssetBundles(outPath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
他会根据inspector面板上指定的assetbundle的名称进行打包,如果没有指定则不进行打包。
2、如果A资源依赖B资源,但是B资源没有明确指定要打包,并且使用了上面的方法进行打包,那么B资源则会自动被打包到A资源中去。
3、unload(false),只会卸载镜像文件。
4、unload(true),会卸载镜像文件和asset文件。
5、合理规划打包的规则,实现引用计数实现资源的管理。
6、参考https://docs.unity3d.com/Manual/AssetBundles-Native.html学习各类包加载方式。