Unity___AB包

AB包#

一些压缩文件,模型,预制体,图片....

Resources和AB包区别#

  1. Resources打包定死,只读,无法修改
  2. 存储位置自定义,压缩方式,后期更新
  3. 减少包体大小
  4. 热更新
    1.资源
    2.脚本

热更新过程#

  1. 获取资源地址
  2. 通过资源对比文件,检测哪些需要热更新,下载

AB包生成的文件#

  1. AB包文件 资源文件
  2. manifest文件 AB包文件信息,当加载时,提供关键信息,资源信息,依赖关系,版本信息
  3. 关键AB包和目录名一样

AB Browser 插件相关参数#

BuildTarget:目标平台
Output Path:目标输出路径
Clear Folders:是否清空文件夹重新打包
Copy To StreamingAssets:是否拷贝到StreamingAssets

NoCompression

不压缩,解压快,包较大不推荐

LZMA

压缩最小,解压慢
缺点:用一个资源要解压所有

LZ4

压缩,相对LZMA大一点点建议使用,用什么解压什么,内存占用低

Build 参数#

ET在资源包中不包含资源的类型信息
FR重新打包时需要重新构建包,和ClearFolders不同,它不会删除不再存在的包
ITTC 增量构建检查时,忽略类型数的更改
Append Hash 将文件哈希值附加到资源包名上
SM 严格模式,如果打包时报错了,则打包直接失败无法成功
DRB 运行时构建

AB包加载资源#

//第一步加载AB包
AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" +“mode1");
//第二步加载AB包中的资源
//只是用名字加载会出现同名不同类型资源分不清
//建议大家用泛型加载或者是Type指定类型
Gameobject obj = ab.LoadAsset<Gameobject>( "cube" );
//Gameobject obj = ab.LoadAsset("cube", typeof(Gameobject)) as Game0bject;
Instantiate(obj);

//AB包不能够重复加载否则报错
//AssetBundle ab2 = AssetBundle.LoadFromFile(Application.streamingAssetsPath + " /"+“model");//加载─个圆
GameObject obj2 = ab2.LoadAsset("Sphere" , typeof(GameObject)) as GameObject;
Instantiate(obj);

卸载加载的AB包#

//卸载所有加载的AB包,参数为true,加载的资源也会被卸载
AssetBundle.UnloadAllAssetBundles(true);
//也可以自己卸载自己,参数同上
ab.Unload(false);

异步加载:协程#

IEnumerator LoadABRes( string ABName,string resName ){
//第一步加载AB包
AssetBundleCreateRequest abcr = AssetBundle.LoadFromFileAsync(Application.streamingAssetsPath+"/"+ABName);
yield return abcr;
//第二步加载资源
AssetBundleRequest abq = abcr.assetBundle.LoadAssetAsync(resName,typeof(Sprite));
yield return abq;
//abq.asset as Sprite;
img. sprite = abq.asset as Sprite;
}

依赖问题#

一个资源用到别的AB包中的资源,只有把所有需要的依赖包全部加载才能正常使用

通过主包 获取依赖信息

//依赖包的关键知识点利用主包获取依赖信息
//加载主包
AssetBundle abNain = AssetBundle.LoadFromFile(Application.streamingAssetsPath + " /" +"pC");
//加载主包中的固定文件
AssetBundleManifest abManifest = abMain.LoadAsset<AssetBundlewanifest>("AssetBundlewanifest");
//从固定文件中得到依赖信息
string[] strs = abManifest.GetAllDependencies( "model");
//得到了依赖包的名字,并加载需要的依赖
for (int i = 0; i < strs.Length; i++){
AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + strs[i]);
}

打包步骤

  • 设置打包对象
  • 生成AssetBundle
  • 上传服务器
  • 下载AssetBundle
  • 加载对象
  • 使用对象

设置打包对象#

设置包名和后缀名

设置打包对象#

在Editor目录下创建脚本,方便快速打包

[CustomEditor(typeof(Tools))]
public class Tools : Editor {
    public override void OnInspectorGUI() {
        base.OnInspectorGUI();
        
    }
    //在上方导航栏显示出菜单
    [MenuItem("Tools/CreateAssetBundle")]
    static void CreateAssetBundle(){
        string path ="AB";
        //不存在就就建立
        if(Directory.Exists(path)==false){
            Directory.CreateDirectory(path);
        }
        // 路径 ,打包方式,平台
        BuildPipeline.BuildAssetBundles(path,BuildAssetBundleOptions.None,BuildTarget.StandaloneWindows64);
        UnityEngine.Debug.Log("Finished");
    }
}

BuildAssetBundleOptions常用参数介绍#

UncompressedAssetBundle:不压缩,包体积大
ChunkBasedCompression:创建AssetBundle时使用LZ4压缩。默认情况是Lzma格式,下载AssetBoundle后立即解压。

材质打包#

如果不打包预制体的材质,则打包后每个预制体的包都会变大

AB包使用方法#

加载AB#

  1. 内存
  2. 文件
  3. WWW
  4. UnityWebRequest
using UnityEngine;
using System.IO;
using System.Collections;
using UnityEngine.Networking;

public class LoadAssetBundle : MonoBehaviour
{
    private void Start()
    {
        StartCoroutine(fromUnityWebRequest());
    }
    // 1. 内存
    IEnumerator fromMemery()
    {
        string path = @"E:\Study\UnityLearns\Demo-AssetBundle\AB\box.3dobj";
        string matpath = @"E:\Study\UnityLearns\Demo-AssetBundle\AB\mat.3dobj";
        byte[] Matbytes = File.ReadAllBytes(matpath);
        byte[] bytes = File.ReadAllBytes(path);
        AssetBundle assetBundle = AssetBundle.LoadFromMemory(bytes);
        AssetBundle matAssetBundle = AssetBundle.LoadFromMemory(Matbytes);
        GameObject obj = assetBundle.LoadAsset("Cube") as GameObject;
        GameObject go = GameObject.Instantiate(obj);
        yield return null;
    }
    // 2. 文件
    IEnumerator fromFileOne()
    {
        string matpath = @"E:\Study\UnityLearns\Demo-AssetBundle\AB\mat.3dobj";
        AssetBundle matAssetBundle = AssetBundle.LoadFromFile(matpath);
        string path = @"E:\Study\UnityLearns\Demo-AssetBundle\AB\box.3dobj";
        AssetBundle ab = AssetBundle.LoadFromFile(path);
        GameObject obj = ab.LoadAsset<GameObject>("cube");
        Instantiate(obj);
        yield return null;
    }
    IEnumerator fromFileAll()
    {
        //1.设置所有预制体包名为一样的

        string path = @"E:\Study\UnityLearns\Demo-AssetBundle\AB\allobj.u3d";
        AssetBundle ab = AssetBundle.LoadFromFile(path);
        object[] objs = ab.LoadAllAssets();
        foreach (var item in objs)
        {
            Instantiate((GameObject)item);
        }
        // Instantiate(obj);
        yield return null;
    }
    // 3. WWW
    //1. 无缓存机制
    IEnumerator fromWWW1()
    {
        //1.本地 file:///

        string path = @"file:///E:\Study\UnityLearns\Demo-AssetBundle\AB\allobj.u3d";
        WWW www = new WWW(path);
        yield return www;
        if (!string.IsNullOrEmpty(www.error))
        {
            Debug.Log(www.error);
            yield break;
        }

        AssetBundle ab = www.assetBundle;
        object[] objs = ab.LoadAllAssets();
        foreach (var item in objs)
        {
            Instantiate((GameObject)item);
        }
        // Instantiate(obj);
        yield return null;
    }
    //2. 有缓存机制
    IEnumerator fromWWW2()
    {
        //1.本地 file:///

        string path = @"file:///E:\Study\UnityLearns\Demo-AssetBundle\AB\allobj.u3d";
        WWW www = WWW.LoadFromCacheOrDownload(path, 1);//删除这个AB文件夹依然可以从缓存中读取到,如果将版本号改为2,则本地无法读取,但是可以读取AB2文件夹
        yield return www;
        if (!string.IsNullOrEmpty(www.error))
        {
            Debug.Log(www.error);
            yield break;
        }

        AssetBundle ab = www.assetBundle;
        object[] objs = ab.LoadAllAssets();
        foreach (var item in objs)
        {
            Instantiate((GameObject)item);
        }
        // Instantiate(obj);
        yield return null;
        www.Dispose();
        www = null;
    }
    // 4. UnityWebRequest
    IEnumerator fromUnityWebRequest()
    {

        // string path = @"file:///E:\Study\UnityLearns\Demo-AssetBundle\AB2\box.3dobj";
        string path= @"http://localhost:8080/AB/allobj.u3d";
        UnityWebRequest unityWebRequest = UnityWebRequestAssetBundle.GetAssetBundle(path);
        yield return unityWebRequest.SendWebRequest();
        AssetBundle ab = DownloadHandlerAssetBundle.GetContent(unityWebRequest);
        // GameObject obj = ab.LoadAsset<GameObject>("cube");
        // Instantiate(obj);
        object[] objs = ab.LoadAllAssets();
        foreach (var item in objs)
        {

            Instantiate((GameObject)item);
            Debug.Log(((GameObject)item).name);
        }
        yield return null;
    }
  //加载依赖
    IEnumerator fromManifest(){
        //略
        yield return null;
    }

}

上传服务器#

我利用的是Tomcat服务器,将AB包放置在webapps文件夹下,通过url:http://localhost:8080/AB/allobj.u3d可以读取到,另外需要在web.xml里面添加配置

    <mime-mapping>
        <extension>u3d</extension>
        <mime-type>application/octet-stream</mime-type>
    </mime-mapping>
posted @   lxp_blog  阅读(114)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示
主题色彩