加载中...

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 @ 2023-07-01 13:43  lxp_blog  阅读(86)  评论(0编辑  收藏  举报