Unity使用AssetBundle(AB包)实现资源的打包,加载和卸载

一、为什么项目开发一般要使用AssetBundle对资源进行打包,加载和卸载?

为什么项目开发一般要使用AssetBundle对资源进行打包,加载和卸载?
主要原因有以下几点:

  1. 游戏资源一般来说只有在被使用到或即将被使用到时才应该被加载进内存中,不应该一直出现在场景里。很容易理解,我刚打开游戏的第一关,我需要将第10关的BOSS提前在内存中加载好吗?这无疑是对内存空间的极大浪费,所以我们要对资源进行合理的加载和卸载,使用时加载,用完后卸载。
  2. Unity对资源进行加载和卸载主要有两种方式:ResourcesAssetBundle。AssetBundle相比于Resources来说,最主要的优势就是对于游戏的资源热更新。比如说,我现在有一个安装包1G大小的手游,现在有一个1M大小的资源A出问题了,我将这个资源A替换成了另一个同样1M大小的资源B,此时差距就出现了:
    (1)如果我使用Resources管理资源,资源是全部存储在安装包中的,那么我替换完成后,为了让用户同步到这次的资源更新,我得再重新将整个游戏打一个新的包,也就是说,仅仅是替换了一个1M的资源,用户却必须重新下载1G的新包进行安装。这无论是从效率上还是用户体验上来说都是非常差劲的。
    (2)如果我使用AssetBundle管理资源,资源是和安装包分离,单独打包的。而且一个游戏的资源一般会按照类型或是逻辑分成很多小包,游戏运行时需要用到什么资源就从对应的包中读取相应的资源。如此一来,当我们替换资源A后,只需要将A资源所在的包(bundle)进行更新,重新将这个bundle发布给用户,直接覆盖原先的bundle即可,替换一个1M的资源可能只需要用户下载2-10M即可完成,基本保证了用户无需下载未改动的部分。
    再说的形象点,我现在有一副画

在这里插入图片描述
说现在需求改了,得在后面加画个太阳。
在这里插入图片描述

如果用Resource就是再拿一张白纸出来重新画一张一模一样的图但是画的时候加了个太阳,而用 AssetBundle就是把需要画太阳的部分切下来,画个太阳,再放回去。
3.使用AssetBundle可以显著减少安装包的大小,因为Unity编译打包是将整个Asset文件夹打包压缩,我们可以将游戏后期才需要的资源(AB包)不放入asset中,等玩家玩到的时候再去下载,安装包越小玩家对游戏的接受程度就越高。

二、使用Unity 的AssetBundle打包资源

1.首先点击需要打包的资源文件(注意不能选择场景里的物体,只能在Asset目录下选择,如果一定要场景里的物体请先保存为prefab存储下来),可以是任何格式的文件,没有限制,在Inspect面板最下方可以看到AssetBundle的两个选项
在这里插入图片描述
第一个选项是该文件所在的包名,选择new自己起一个名字。第二个选项是这个包的后缀名,也可以随意取,但注意后缀名不能是像txt,rar,jpg这种,读取的时候会出错。包名和后缀都相同的资源就会被打在同一个包里。
在这里插入图片描述

2.Unity本身支持AssetBundle,有写好的API,直接使用即可,无需安装任何插件,唯一麻烦的一点是Unity只提供了API,没有提供一键打包的选项。需要手动书写一个工具脚本调用内置的打包命令。这里本人已经写好了三端都可以打包的脚本,需要的自取。
如果想要自己学习如何书写打包脚本,请移步AssetBundle的使用方法详解,视频详细描述了打包的细节和读取的方法。

注意必须在Asset下创建一个叫Editor的文件夹,脚本必须放在Editor文件夹下才能使用。Windows平台的路径可以随意选择,Andriod和IOS的存储路径是约定好不能变更的。

using UnityEditor;
using System.IO;
public class AssetBuldle : Editor
{
    
    
    [MenuItem("Tools/CreatAssetBundle for Android")]
  
    static void CreatAssetBundle()
    {
    
    

        string path = "Assets/StreamingAssets";
        if (!Directory.Exists(path))
        {
    
    
            Directory.CreateDirectory(path);
        }
        BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.UncompressedAssetBundle, BuildTarget.Android);
        UnityEngine.Debug.Log("Android Finish!");
    }

    [MenuItem("Tools/CreatAssetBundle for IOS")]
    static void BuildAllAssetBundlesForIOS()
    {
    
    
        string dirName = "AssetBundles/IOS";
        if (!Directory.Exists(dirName))
        {
    
    
            Directory.CreateDirectory(dirName);
        }
        BuildPipeline.BuildAssetBundles(dirName, BuildAssetBundleOptions.CollectDependencies, BuildTarget.iOS);
        UnityEngine.Debug.Log("IOS Finish!");

    }


    [MenuItem("Tools/CreatAssetBundle for Win")]
    static void CreatPCAssetBundleForwINDOWS()
    {
    
    
        string path = "AB";
        if (!Directory.Exists(path))
        {
    
    
            Directory.CreateDirectory(path);
        }
        BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
        UnityEngine.Debug.Log("Windows Finish!");
    }
}

将该脚本放入Editor文件夹下之后,上方菜单栏就会出现Toos的选项,在这里插入图片描述
此时在勾选好需要打包的资源后选择对应的平台就可以一键打包了,比如点击Windows的打包,等待一会,下方日志就会显示
在这里插入图片描述
此时可以去看其所在的路径,该脚本Windows的存储路径在工程文件下的AB文件夹中
在这里插入图片描述
可以看到我们的资源成功打包了,下方的texture是我以前设置的另一个包,和上方的jojo无关。每个资源包被打出来后都会有一个同名的manifest文件,这个文件记录了这个资源包中的资源信息。
在这里插入图片描述
可以看到Asset下的两个资源名就是我们打包时的资源,说明没有问题,此时打包的工作就此结束。

三、Unity 加载和卸载AssetBundle

加载和卸载直接在脚本中使用相关API即可,下面是一个简单的小测试。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ABtest : MonoBehaviour
{
    
    
    string path = "AB/jojo.czh";//包体的路径
    private AssetBundle asset;//声明一个AB包
    void Update()
    {
    
    

        if (Input.GetKeyDown(KeyCode.L))
        {
    
    
            asset = AssetBundle.LoadFromFile(path);
            asset.LoadAsset("jojo");//通过资源名加载单个资源
            asset.LoadAsset("Giorno");
            //asset。LoadAllAsset() 加载全部资源
            Debug.Log("Load AssetBundle");
        }

        if (Input.GetKeyDown(KeyCode.U))
        {
    
    
            asset.Unload(true);//卸载全部资源
            Debug.Log("Unload AssetBundle");

        }
    }
}

注意Andriod和IOS的路径写法特殊,建议先查阅相关资料,直接写会出错。之后如果有时间本人单独写一下路径的注意事项。

将脚本挂载到一个空物体,运行起来,观察profiler
在这里插入图片描述
目前是无操作时的内存情况,接着我们点击L键进行读取:
在这里插入图片描述
出现了! jojo.czh包中的两张图被加载进了内存里。
我们再点击U键进行卸载:
在这里插入图片描述
Texture不见了,说明卸载也成功了。

至此,AssetBundle的打包,加载和卸载都已完成。当然其中还有很多的细节没有说明,本文旨在介绍使用AssetBundle的流程,给刚接触的朋友一个简单的了解。如果有问题或是建议请评论或私聊,谢谢!

猜你喜欢

转载自blog.csdn.net/qq_45035709/article/details/113522534