Unity之AssetBundle入门学习

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/Csoap2/article/details/102635776

assetbundle官方文档地址

用处

1,AssetBundle是一个压缩包包含模型、贴图、预制体、声音、甚至整个场景,可以在游戏运行的时候被加载;
2,AssetBundle自身保存着互相的依赖关系;
3,压缩包可以使用LZMA和LZ4压缩算法,减少包大小,更快的进行网络传输;
4,把一些可以下载内容放在AssetBundle里面,可以减少安装包的大小;

可以归为两点:

1,它是一个存在于硬盘上的文件。可以称之为压缩包。这个压缩包可以认为是一个文件夹,里面包含了多个文件。这些文件可以分为两类:serialized file 和 resource files。(序列化文件和源文件)
serialized file:资源被打碎放在一个对象中,最后统一被写进一个单独的文件(只有一个)
resource files:某些二进制资源(图片、声音)被单独保存,方便快速加载
2,它是一个AssetBundle对象,我们可以通过代码从一个特定的压缩包加载出来的对象。这个对象包含了所有我们当初添加到这个压缩包里面的内容,我们可以通过这个对象加载出来使用。

建立
using UnityEditor;
using System.IO;

public class CreateAssetBundles
{
    [MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        string assetBundleDirectory = "Assets/AssetBundles";
        if(!Directory.Exists(assetBundleDirectory))
        {
            Directory.CreateDirectory(assetBundleDirectory);
        }
        BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);
    }
}
BuildAssetBundleOptions

BuildAssetBundleOptions.None:使用LZMA算法压缩,压缩的包更小,但是加载时间更长。使用之前需要整体解压。一旦被解压,这个包会使用LZ4重新压缩。使用资源的时候不需要整体解压。在下载的时候可以使用LZMA算法,一旦它被下载了之后,它会使用LZ4算法保存到本地上。
BuildAssetBundleOptions.UncompressedAssetBundle:不压缩,包大,加载快
BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4压缩,压缩率没有LZMA高,但是我们可以加载指定资源而不用解压全部。

注意使用LZ4压缩,可以获得可以跟不压缩想媲美的加载速度,而且比不压缩文件要小。
详细参数介绍地址

生成
在这里插入图片描述

用代码通过ab生成物体
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class LoadFromFile : MonoBehaviour
{
    void Start()
    {
        AssetBundle ab = AssetBundle.LoadFromFile("Assets/AssetBundles/scene/wall.unity3d");
        if (ab == null)
        {
            Debug.Log("Faild to load AssetBundle");
            return;
        }
        var prefab = ab.LoadAsset<GameObject>("CubeWall");
        Instantiate(prefab);
    }
}
AssetBundle 分组策略

1,逻辑实体分组
a,一个UI界面或者所有UI界面一个包(这个界面里面的贴图和布局信息一个包)
b,一个角色或者所有角色一个包(这个角色里面的模型和动画一个包)
c,所有的场景所共享的部分一个包(包括贴图和模型)
2,按照类型分组
所有声音资源打成一个包,所有shader打成一个包,所有模型打成一个包,所有材质打成一个包
3,按照使用分组
把在某一时间内使用的所有资源打成一个包。可以按照关卡分,一个关卡所需要的所有资源包括角色、贴 图、声音等打成一个包。也可以按照场景分,一个场景所需要的资源一个包

总结

1,把经常更新的资源放在一个单独的包里面,跟不经常更新的包分离
2,把需要同时加载的资源放在一个包里面
3,可以把其他包共享的资源放在一个单独的包里面
4,把一些需要同时加载的小资源打包成一个包
5,如果对于一个同一个资源有两个版本,可以考虑通过后缀来区分 v1 v2 v3 unity3dv1 unity3dv2

依赖打包

在这里插入图片描述
仅需要对公用的贴图材质设置ab,打包自动生成依赖,避免重复资源
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

加载

AssetBundle.LoadFromFile
在这里插入图片描述
UnityWebRequest
在这里插入图片描述
Loading Assets from AssetBundles

//一般
T objectFromBundle = bundleObject.LoadAsset<T>(assetName);
//GameObject
GameObject gameObject = loadedAssetBundle.LoadAsset<GameObject>(assetName);
//所有资源
Unity.Object[] objectArray = loadedAssetBundle.LoadAllAssets();
加载Manifests

加载Manifests文件可以处理资源的依赖
官方例子

AssetBundle assetBundle = AssetBundle.LoadFromFile(manifestFilePath);
AssetBundleManifest manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
string[] dependencies = manifest.GetAllDependencies("assetBundle"); //Pass the name of the bundle you want the dependencies for.
foreach(string dependency in dependencies)
{
    AssetBundle.LoadFromFile(Path.Combine(assetBundlePath, dependency));
}

个人实例

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;

public class LoadFromFile : MonoBehaviour
{
    IEnumerator Start()
    {
        string uri = @"http://localhost/AssetBundles/cubewall.unity3d";
        UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(uri);
        yield return request.Send();
        AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);
        GameObject cube = bundle.LoadAsset<GameObject>("CubeWall");
        Instantiate(cube);

        AssetBundle mainfesetAB = AssetBundle.LoadFromFile("Assets/AssetBundles/AssetBundles");
        AssetBundleManifest mainfest = mainfesetAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

        string[] strs = mainfest.GetAllDependencies("cubewall.unity3d");
        foreach (string name in strs)
        {
            Debug.Log(name);
            AssetBundle.LoadFromFile("Assets/AssetBundles/" + name);
        }
    }
}

在这里插入图片描述
预制体和依赖的皮肤也加载到

AssetBundle的卸载

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
因此调用 AssetBundle.Unload(false)有可能会导致多余的内存被占用,而且只能切换场景或者使用Resources.UnloadUnusedAssets卸载,推荐使用 AssetBundle.Unload(true)
卸载总结
通常,使用assetbundle.Unload(false)不会导致理想的情况。大多数项目都应该使用assetbundle.Unload(true)来避免在内存中复制对象。
大多数项目都应该使用assetbundle.卸载(true)并采用一种方法来确保对象不会被复制。两个常见的方法是:
1.在应用程序的生命周期中有定义良好的点,在这个过程中,临时的assetbundle被卸载,例如在级别或加载屏幕期间。
2.仅当所有的组成对象都未使用时,维护个别对象的引用计数和卸载assetbundle。这允许应用程序在不重复内存的情况下卸载和重新加载单个对象。
如果应用程序必须使用assetbundle.卸载(false),AssetBundle.Unload(false)卸载所有没被使用的资源,当某个资源被引用时候无法被卸载,该资源会与ab失去联系,下次再ab中运用到该类型资源,导致内存中多存在一份资源。个别资源会多余。(如上3图解释),那么单个对象只能以两种方式卸载:

1.在场景和代码中,消除对一个不需要的对象的所有引用。完成此操作之后,调用Resources.unloadunusedassets。
2.非附加的加载一个场景。这将销毁当前场景中的所有对象并调用资源并自动调用UnloadUnusedAssets。

关于文件校验

CRC MD5 SHA1
相同点:
CRC、MD5、SHA1都是通过对数据进行计算,来生成一个校验值,该校验值用来校验数据的完整性。
不同点:

  1. 算法不同。CRC采用多项式除法,MD5和SHA1使用的是替换、轮转等方法;
  2. 校验值的长度不同。CRC校验位的长度跟其多项式有关系,一般为16位或32位;MD5是16个字节(128位);SHA1是20个字节(160位);
  3. 校验值的称呼不同。CRC一般叫做CRC值;MD5和SHA1一般叫做哈希值(Hash)或散列值;
  4. 安全性不同。这里的安全性是指检错的能力,即数据的错误能通过校验位检测出来。CRC的安全性跟多项式有很大关系,相对于MD5和SHA1要弱很多;MD5的安全性很高,不过大概在04年的时候被山东大学的王小云破解了;SHA1的安全性最高。
  5. 效率不同,CRC的计算效率很高;MD5和SHA1比较慢。
  6. 用途不同。CRC一般用作通信数据的校验;MD5和SHA1用于安全(Security)领域,比如文件校验、数字签名等。
AssetBundle补丁

在修补系统中要解决的更困难的问题是检测要替换的AssetBundle。修补系统需要两个信息列表:
1.当前下载的AssetBundle的列表及其版本信息
2.服务器上的AssetBundle列表及其版本信息
修补程序应下载服务器端AssetBundle列表,并比较AssetBundle列表。缺少的AssetBundles或版本信息已更改的AssetBundles,应重新下载。

其他问题

1,依赖包重复问题
a,把需要共享的资源打包到一起
b,分割包,这些包不是在同一时间使用的
c,把共享部分打包成一个单独的包
2,图集重复问题
将图集中所有图片打包成一个单独的AB包,让其他AB包依赖它

AssetBundle浏览工具

unity官方AB浏览工具github
在这里插入图片描述
下载完新建个目录放置于Editor目录下
Window > AssetBundle Browser.开始进行AB操作

猜你喜欢

转载自blog.csdn.net/Csoap2/article/details/102635776
今日推荐