添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接


Unity2021 AssetBundle资源打包

AssetBundle是一种动态地资源加载方式。如果一次性地把资源导到游戏里,会使得游戏过大。可以把一些资源(例如:预制体、image、材质、music)与游戏主体分离,然后把这些分离的资源放到服务器上。当游戏需要该资源的时候就从服务器加载该资源,从而实现了资源的动态更新。

ios下 unity手机重启 unity build ios_游戏引擎

1. 打包的主要步骤

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

2.设置打包对象

  • 首先,设置打包对象。
  • 新建Prefabs文件夹,把图片放在Prefabs文件夹中。
  • 新建一个材质球,把材质球添加到beijing中。
  • 点击beijing预制体,可以看到Inspector窗口的右下角有个AssetBudle选项,第一个下拉菜单设置打包名称,第二个设置拓展名,都可以通过new自定义。
  • 在这里,把三幅图片预制体都设置成allres打包名,以及u3d拓展名。

ios下 unity手机重启 unity build ios_unity_02

3.生成AssetBundle

  • 设置能够快速打包的编辑菜单
using System.IO;
using UnityEngine;
using UnityEditor;
public class MyTools : Editor
    [MenuItem("Tools/CreateBundle")]
    static void CreateAssetBundle()
        string path = "AB";//写入文件
        if (!Directory.Exists(path))
            Directory.CreateDirectory(path);
        //path:打包路径,BuildAssetBundleOptions.None:打包方式, BuildTarget.StandaloneWindows64:打包的目标平台
        BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
        Debug.Log("Created Bundle!");
}
  • 打包参数的设置

None

不使用任何特殊选项构建 assetBundle。

UncompressedAssetBundle

Don’t compress the data when creating the AssetBundle.

DisableWriteTypeTree

不包括 AssetBundle 中的类型信息。

DeterministicAssetBundle

使用存储在资源包中对象的 ID 的哈希构建资源包。

ForceRebuildAssetBundle

强制重新构建 assetBundle。

IgnoreTypeTreeChanges

在执行增量构建检查时忽略类型树更改。

AppendHashToAssetBundleName

向 assetBundle 名称附加哈希。

ChunkBasedCompression

创建 AssetBundle 时使用基于语块的 LZ4 压缩。

StrictMode

如果在此期间报告任何错误,则构建无法成功。

DryRunBuild

进行干运行构建。

DisableLoadAssetByFileName

禁用按照文件名称查找资源包 LoadAsset。

DisableLoadAssetByFileNameWithExtension

禁用按照带扩展名的文件名称查找资源包 LoadAsset。

AssetBundleStripUnityVersion

在构建过程中删除存档文件和序列化文件头中的 Unity 版本号。

  • 设置完成后,经过引擎的编译,编辑栏上会出现Tools工具栏,点击Tools->CreateBundle,就会在工程目录下生成AB文件夹,里面有各种刚刚设置好的打包对象资源。

ios下 unity手机重启 unity build ios_unity_03

  • u3d拓展名的文件为资源文件。
  • manifest文件为资源的一些信息

ios下 unity手机重启 unity build ios_System_04

  • 打开manifest文件
  • ①为资源路径。
  • ②为依赖对象的路径,因为beijing预制体绑定了一个材质,因此此依赖对象也使beijing预制体的材质对象。

ios下 unity手机重启 unity build ios_unity_05

4.读取打包资源

读取打包资源,一般有4种方法。分别为从内存种读取、从文件中读取、通过WWW方式读取、unityWebRequest读取(推荐)。

1. 从内存中读取

using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundle : MonoBehaviour
    // Start is called before the first frame update
    void Start()
        StartCoroutine(fromMemory());
        //StartCoroutine(fromFile()); //读取单个文件
        //StartCoroutine(fromAllFile());//读取多个文件
        //StartCoroutine(fromWWW1());
        //StartCoroutine(fromWWW2());
        //StartCoroutine(fromunityWebRequest());
    // Update is called once per frame
    void Update()
    IEnumerator fromMemory()
        string path = @"D:\Unity3d\Project\AssetBundleDemo\AB\background.u3d";
        string matpath = @"D:\Unity3d\Project\AssetBundleDemo\AB\mat1.u3d";
        byte[] bytes = File.ReadAllBytes(path);
        byte[] matbytes = File.ReadAllBytes(matpath);
        AssetBundle assetBundle = AssetBundle.LoadFromMemory(bytes);//以内存的方式加载
        AssetBundle matassetBundle = AssetBundle.LoadFromMemory(matbytes);//材质不需要实例化,只需要加载到内存就可以了
        GameObject prefabGo = assetBundle.LoadAsset("beijing") as GameObject;//实例化游戏对象
        GameObject.Instantiate(prefabGo);
        yield return null;
}
  • 点击运行,beijing的资源和beijing所依赖的材质都加载到场景了。

ios下 unity手机重启 unity build ios_游戏引擎_06

2. 从文件中读取

  • 单文件方式
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundle : MonoBehaviour
    // Start is called before the first frame update
    void Start()
        //StartCoroutine(fromMemory());
        StartCoroutine(fromFile()); //读取单个文件
        //StartCoroutine(fromAllFile());//读取多个文件
        //StartCoroutine(fromWWW1());
        //StartCoroutine(fromWWW2());
        //StartCoroutine(fromunityWebRequest());
    IEnumerator fromFile()
        string path = @"D:\Unity3d\Project\AssetBundleDemo\AB\background.u3d";
        string matpath = @"D:\Unity3d\Project\AssetBundleDemo\AB\mat1.u3d";
        AssetBundle assetBundle = AssetBundle.LoadFromFile(path);
        AssetBundle matassetBundle = AssetBundle.LoadFromFile(matpath);
        GameObject preobj = assetBundle.LoadAsset("beijing") as GameObject;
        GameObject.Instantiate(preobj);
        yield return null;
}
  • 多文件方式
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundle : MonoBehaviour
    // Start is called before the first frame update
    void Start()
        //StartCoroutine(fromMemory());
        //StartCoroutine(fromFile()); //读取单个文件
        StartCoroutine(fromAllFile());//读取多个文件
        //StartCoroutine(fromWWW1());
        //StartCoroutine(fromWWW2());
        //StartCoroutine(fromunityWebRequest());
    IEnumerator fromAllFile()
        string path = @"D:\Unity3d\Project\AssetBundleDemo\AB\allres.u3d";
        string matpath = @"D:\Unity3d\Project\AssetBundleDemo\AB\mat1.u3d";
        AssetBundle assetBundle = AssetBundle.LoadFromFile(path);
        Object[] objlist = assetBundle.LoadAllAssets();
        foreach (var obj in objlist)
            GameObject.Instantiate(obj as GameObject);
        AssetBundle matassetBundle = AssetBundle.LoadFromFile(matpath);
        yield return null;
}
  • 点击运行,所有的资源都加载到场景里

ios下 unity手机重启 unity build ios_unity_07

3.通过WWW方式读取

  • 无缓存WWW方式
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundle : MonoBehaviour
    // Start is called before the first frame update
    void Start()
        //StartCoroutine(fromMemory());
        //StartCoroutine(fromFile()); //读取单个文件
        //StartCoroutine(fromAllFile());//读取多个文件
        StartCoroutine(fromWWW1());
        //StartCoroutine(fromWWW2());
        //StartCoroutine(fromunityWebRequest());
    //WWW无缓存机制
    IEnumerator fromWWW1()
        //物体部分
        string path = @"file:///D:\Unity3d\Project\AssetBundleDemo\AB\allres.u3d";
        WWW www = new WWW(path);
        yield return www;
        //如果错误信息不空,则打印错误信息,并且中断
        if (!string.IsNullOrEmpty(www.error))
            Debug.Log(www.error);
            yield break;
        AssetBundle asset = www.assetBundle;
        GameObject pre = asset.LoadAsset("beijing") as GameObject;
        GameObject.Instantiate(pre);
        //材质部分
        string matpath = @"file:///D:\Unity3d\Project\AssetBundleDemo\AB\mat1.u3d";
        WWW matwww = new WWW(matpath);
        if (!string.IsNullOrEmpty(matwww.error))
            Debug.Log(matwww.error);
            yield break;
        AssetBundle matasset = matwww.assetBundle;
        www.Dispose();
        www = null;
        matwww.Dispose();
        matwww = null;
        yield return null;
}
  • 有缓存方式
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundle : MonoBehaviour
    // Start is called before the first frame update
    void Start()
        //StartCoroutine(fromMemory());
        //StartCoroutine(fromFile()); //读取单个文件
        //StartCoroutine(fromAllFile());//读取多个文件
        //StartCoroutine(fromWWW1());
        StartCoroutine(fromWWW2());
        //StartCoroutine(fromunityWebRequest());
    //WWW缓存机制
    IEnumerator fromWWW2()
        //物体部分
        string path = @"file:///D:\Unity3d\Project\AssetBundleDemo\AB\allres.u3d";
        WWW www = WWW.LoadFromCacheOrDownload(path, 1);//如果缓存中有对应的版本,则直接从缓存中读取,如果没有则返回一个错误信息
        //如果错误信息不空,则打印错误信息,并且中断
        //得到错误信息后,可以重定向路径
        if (!string.IsNullOrEmpty(www.error))
            Debug.Log(www.error);
            yield break;
        AssetBundle asset = www.assetBundle;
        GameObject pre = asset.LoadAsset("beijing") as GameObject;
        GameObject.Instantiate(pre);
        //材质部分
        string matpath = @"file:///D:\Unity3d\Project\AssetBundleDemo\AB\mat1.u3d";
        WWW matwww = WWW.LoadFromCacheOrDownload(matpath,1);
        if (!string.IsNullOrEmpty(matwww.error))
            Debug.Log(matwww.error);
            yield break;
        AssetBundle matasset = matwww.assetBundle;
        www.Dispose();
        www = null;
        matwww.Dispose();
        matwww = null;
        yield return null;
}

4.通过unityWebRequest读取

using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundle : MonoBehaviour
    // Start is called before the first frame update
    void Start()
        //StartCoroutine(fromMemory());
        //StartCoroutine(fromFile()); //读取单个文件
        //StartCoroutine(fromAllFile());//读取多个文件
        //StartCoroutine(fromWWW1());
        //StartCoroutine(fromWWW2());
        StartCoroutine(fromunityWebRequest());
    //unityWebRequest
    IEnumerator fromunityWebRequest()
        //物体部分
        string path = @"file:///D:\Unity3d\Project\AssetBundleDemo\AB\allres.u3d";
        UnityWebRequest unityWebRequest;
        unityWebRequest = UnityWebRequestAssetBundle.GetAssetBundle(path);
        yield return unityWebRequest.SendWebRequest();//发送请求获取资源
        AssetBundle asset = DownloadHandlerAssetBundle.GetContent(unityWebRequest);//获取上面请求得到的资源
        GameObject pre = asset.LoadAsset("beijing") as GameObject;
        GameObject.Instantiate(pre);
        //材质部分
        string matpath = @"file:///D:\Unity3d\Project\AssetBundleDemo\AB\mat1.u3d";
        UnityWebRequest matunityWebRequest;
        matunityWebRequest = UnityWebRequestAssetBundle.GetAssetBundle(matpath);
        yield return matunityWebRequest.SendWebRequest();
        AssetBundle matasset = DownloadHandlerAssetBundle.GetContent(matunityWebRequest);
        yield return null;