AssetBundle

https://blog.csdn.net/zwg739424406/article/details/79629106

一、AssetBundle定义和作用(后面简称AB)

官方介绍:https://docs.unity3d.com/Manual/AssetBundlesIntro.html


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

 


二、什么是AssetBundle

可归为两点


1.它是一个存在于硬盘上的文件。可以称之为压缩包。这个压缩包可以认为是一个文件夹,里面包含了多个文件。这些文件可以分为两类:serialized file 和 resource files。(序列化文件和源文件)


  serialized file:资源(在游戏场景中才能被识别如:模型、预制体)被打碎放在一个对象中,最后统一被写进一个单独的文件(只有一个) 
  resource files:某些二进制资源(可直接在电脑上读取如:图片、声音)被单独保存,方便快速加载

2.它是一个AssetBundle对象,我们可以通过代码从一个特定的压缩包加载出来的对象。这个对象包含了所有我们当初添加到这个压缩包里面的内容,我们可以通过这个对象加载出来使用。

 


三、AssetBundle使用流程(简称AB)

1. 指定资源的AssetBundle属性 

    1. 这儿 (xxx/Cube) == (xxx/cube)   是不区分大小写的
1

2. 构建AssetBundle包 


1.根目录Assets下创建一个Editor文件夹,再创建一个.cs文件使用下方代码
2.点击菜单栏  Assets -> Build AssetBundles,打包成功后在目录【Assets/AssetBundles】中就能看到打包好的资源

public class CreateAssetBundles
{
        //相当于是拓展编译器,在Assets下创建一个Build AssetBundles菜单
    [MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        //string assetBundleDirectory = Path.Combine(Application.streamingAssetsPath, "AssetBundles");//"Assets/AssetBundles";
        string assetBundleDirectory = "Assets/AssetBundles";
        if (!Directory.Exists(assetBundleDirectory))
        {
            Directory.CreateDirectory(assetBundleDirectory);
        }
        //打包的输出路径、打包方式、平台
        /* BuildAssetBundleOptions
         * BuildAssetBundleOptions.None:使用LZMA算法压缩,压缩的包更小,但是加载时间更长。使用之前需要整体解压。
         *          一旦被解压,这个包会使用LZ4重新压缩。使用资源的时候不需要整体解压。在下载的时候可以使用LZMA算法,
         *          一旦它被下载了之后,它会使用LZ4算法保存到本地上。
         * BuildAssetBundleOptions.UncompressedAssetBundle:不压缩,包大,加载快
         * BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4压缩,压缩率没有LZMA高,但是我们可以加载指定资源而不用解压全部。
         */
        BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
    }
}1


 

3. 上传AB包到服务器  


 一般都要在本地调试,等游戏发布时才会上次到服务器

4. 加载AB包和包里面的资源(本地、服务端)  


      这里有个知识点协程:http://www.cnblogs.com/neverdie/p/3792766.html#_nav_5

public class LoadFromFileExample : MonoBehaviour
{
    //LoadFromFile本地加载  LoadFromMemory加载字节流
    void Start() {
        //如果材质是独立的一个包,就需要加载材质
        AssetBundle share = AssetBundle.LoadFromFile("Assets/AssetBundles/material.test");
        //加载模型
        AssetBundle ab = AssetBundle.LoadFromFile("Assets/AssetBundles/scene/sphere.test");
        //从内存加载
        //AssetBundle ab = AssetBundle.LoadFromMemory(File.ReadAllBytes(path));
        if (ab == null)
        {
            Debug.Log("Failed to load AssetBundle!");
            return;
        }
        var prefab = ab.LoadAsset<GameObject>("Sphere");
        GameObject.Instantiate(prefab);
    }


    //UnityWebRequest 服务端或者本地加载
    IEnumerator Start()
    {
        //服务器地址
        string uri = @"http://localhost//AssetBundles/scene/sphere.test";
        //本地地址
        //string uri = @"file://D:/Unity3d/APlan_Siki/09_AssetBundleProject/Assets/AssetBundles/scene/sphere.test";
        UnityEngine.Networking.UnityWebRequest request = UnityEngine.Networking.UnityWebRequest.GetAssetBundle(uri, 0);
        yield return request.Send();//开始下载到缓存
        AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);
        var prefab = ab.LoadAsset<GameObject>("Sphere");
        GameObject.Instantiate(prefab);
    }
}

 


  
 

 

四、AssetBundle分组策略 (仅供参考)


1.逻辑实体分组 
a. 一个UI界面或者所有UI界面一个包(这个界面里面的贴图和布局信息一个包) 
b. 一个角色或者所有角色一个包(这个角色里面的模型和动画一个包) 
c. 所有的场景所共享的部分一个包(包括贴图和模型)
2.按照类型分组 
所有声音资源打成一个包,所有shader打成一个包,所有模型打成一个包,所有材质打成一个包
3.按照使用分组 
把在某一时间内使用的所有资源打成一个包。可以按照关卡分,一个关卡所需要的所有资源包括角色、贴图、声音等打成一个包。也可以按照场景分,一个场景所需要的资源一个包
4.把经常更新的资源放在一个单独的包里面,跟不经常更新的包分离
5.把需要同时加载的资源放在一个包里面
6.依赖打包:可以把其他包共享的资源放在一个单独的包里面(避免同一份资源跟多个依赖的perfab打包在一起)
7.把一些需要同时加载的小资源打包成一个包
8.如果对于一个同一个资源有两个版本,可以考虑通过后缀来区分  v1  v2  v3  unity3dv1 unity3dv2

 


五、通过Manifest文件得到某个包所有的依赖

 

//AssetBundles的路径  获取AssetBundles
AssetBundle assetBundle = AssetBundle.LoadFromFile("Assets/AssetBundles/AssetBundles");
//固定不变   得到AssetBundles.manifest
AssetBundleManifest manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//哪个的包?  得到这个包的所有依赖
string[] dependencies = manifest.GetAllDependencies("scene/sphere.test"); 
foreach (string dependency in dependencies)
{
     AssetBundle.LoadFromFile(Path.Combine("Assets/AssetBundles", dependency));//加载这个包的依赖
}

 

六、AssetBundle的卸载


卸载有两个方面: 1.减少内存使用 2.有可能导致丢失
所以什么时候去卸载资源: 1.关卡切换、场景切换  2.资源没被用的时候 调用
个别资源怎么卸载: 1.通过 Resources.UnloadUnusedAssets. 2.场景切换的时候   
AssetBundle.Unload(true)卸载所有资源,即使有资源被使用着
AssetBundle.Unload(false)卸载所有没用被使用的资源

 


七、关于文件校验 CRC MD5 SHA1


相同点: 
1.都是通过对数据进行计算,来生成一个校验值,该校验值用来校验数据的完整性。
不同点: 
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)领域,比如文件校验、数字签名等。

 


八、AssetBundles浏览工具

官网介绍:https://docs.unity3d.com/Manual/AssetBundles-Browser.html 
工具Git地址:https://github.com/Unity-Technologies/AssetBundles-Browser 
将Editor导入我们的工程,然后点击  Window–>AssetBundle Browser 就会弹出工具界面,可以对打包的资源一目了然。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值