IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity笔记之AssetBundle打包和加载(场景和预制体) -> 正文阅读

[游戏开发]Unity笔记之AssetBundle打包和加载(场景和预制体)

需求:实现用AssetBundle打包和加载场景、预制体。
这是参照一位大佬的拿来改了一点,但是现在没找到大佬的文章,就先这样吧。

实现打AB包方法一:

打包工具AssetBundleBuilder.cs

using UnityEngine;
using UnityEditor;
using System.IO;

/// <summary>
/// 资源包打包工具
/// </summary>
public class AssetBundleBuilder : EditorWindow
{
    [MenuItem("打包/Windows/资源包和场景")]
    public static void BuildAbsAndScenesWindows()
    {
        AssetBundleBuilder assetBundleBuilder = EditorWindow.GetWindow<AssetBundleBuilder>();
        assetBundleBuilder.Show();

        //
    }
    static string outPath;
    private void OnGUI()
    {
        GUILayout.Space(10);
        GUI.skin.label.fontSize = 12;
        GUI.skin.label.alignment = TextAnchor.MiddleLeft;
        GUILayout.Label("AssetBundle文件名称:", GUILayout.MaxWidth(160));
        outPath = EditorGUILayout.TextField(outPath);
        EditorGUI.EndDisabledGroup();

        //string s = EditorGUILayout.TextArea("s");
        if (GUILayout.Button("开始打包场景和资源"))
        {
            BuildAbsAndScenes(BuildTarget.StandaloneWindows);
        }

        //GUILayout.EndVertical();

        //EndWindows();
    }

    [MenuItem("打包/Android/资源包和场景")]
    public static void BuildAbsAndScenesAndroid()
    {
        BuildAbsAndScenes(BuildTarget.Android);
    }

    [MenuItem("打包/IOS/资源包和场景")]
    public static void BuildAbsAndScenesIOS()
    {
        BuildAbsAndScenes(BuildTarget.iOS);
    }

    [MenuItem("打包/Windows/资源包")]
    public static void BuildAbsWindows()
    {
        BuildAssetBundles(BuildTarget.StandaloneWindows);
    }

    [MenuItem("打包/Android/资源包")]
    public static void BuildAbsAndroid()
    {
        BuildAssetBundles(BuildTarget.Android);
    }

    [MenuItem("打包/IOS/资源包")]
    public static void BuildAbsIOS()
    {
        BuildAssetBundles(BuildTarget.iOS);
    }

    [MenuItem("打包/Windows/场景")]
    public static void BuildScenesWindows()
    {
        BuildScenes(BuildTarget.StandaloneWindows);
    }

    [MenuItem("打包/Android/场景")]
    public static void BuildScenesAndroid()
    {
        BuildScenes(BuildTarget.Android);
    }

    [MenuItem("打包/IOS/场景")]
    public static void BuildScenesIOS()
    {
        BuildScenes(BuildTarget.iOS);
    }

    // 打包AssetBundle和Scenes
    public static void BuildAbsAndScenes(BuildTarget platform)
    {
        BuildAssetBundles(platform);
        BuildScenes(platform);
    }

    // 打包AssetBundles
    private static void BuildAssetBundles(BuildTarget platform)
    {
        // 输出路径
        //string outPath = Application.streamingAssetsPath + "/Abs";
        if (!Directory.Exists(outPath)) Directory.CreateDirectory(outPath);
        EditorUtility.DisplayProgressBar("信息", "打包资源包", 0f);
        BuildPipeline.BuildAssetBundles(outPath, BuildAssetBundleOptions.DeterministicAssetBundle, platform);
        AssetDatabase.Refresh();
        Debug.Log("所有资源包打包完毕");
    }

    // 打包Scenes
    private static void BuildScenes(BuildTarget platform)
    {
        // 指定场景文件夹和输出路径
        string scenePath = Application.dataPath + "/AbResources/Scenes";
        //string outPath = Application.streamingAssetsPath + "/Abs/";

        if (Directory.Exists(scenePath))
        {
            // 创建输出文件夹
            if (!Directory.Exists(outPath)) Directory.CreateDirectory(outPath);

            // 查找指定目录下的场景文件
            string[] scenes = GetAllFiles(scenePath, "*.unity");
            for (int i = 0; i < scenes.Length; i++)
            {
                string url = scenes[i].Replace("\\", "/");
                int index = url.LastIndexOf("/");
                string scene = url.Substring(index + 1, url.Length - index - 1);
                string msg = string.Format("打包场景{0}", scene);
                EditorUtility.DisplayProgressBar("信息", msg, 0f);
                scene = scene.Replace(".unity", ".scene");
                Debug.Log(string.Format("打包场景{0}到{1}", url, outPath + scene));
                BuildPipeline.BuildPlayer(scenes, outPath + scene, BuildTarget.StandaloneWindows, BuildOptions.BuildAdditionalStreamedScenes);
                AssetDatabase.Refresh();
            }
            EditorUtility.ClearProgressBar();
            Debug.Log("所有场景打包完毕");
        }
    }

    /// <summary> 获取文件夹和子文件夹下所有指定类型文件 </summary>
    private static string[] GetAllFiles(string directory, params string[] types)
    {
        if (!Directory.Exists(directory)) return new string[0];
        string searchTypes = (types == null || types.Length == 0) ? "*.*" : string.Join("|", types);
        string[] names = Directory.GetFiles(directory, searchTypes, SearchOption.AllDirectories);
        return names;
    }

}

加载ABTest.cs

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class ABTest : MonoBehaviour
{

    public Text textProgress;
    private void Awake()
    {
        //DontDestroyOnLoad(gameObject);
        //StartCoroutine(DownloadPrefab());
        //StartCoroutine(DownloadScene());

        LoadScene(Application.streamingAssetsPath + "/Abs/" + "test");
        LoadPrefabs(Application.streamingAssetsPath + "/Abs/" + "cube.ab");
    }
    public void LoadPrefabs(string url)
    {
        StartCoroutine(DownloadPrefab(url));
    }
    IEnumerator DownloadPrefab(string url)
    {
        //ab包的地址
        //string url = Application.streamingAssetsPath + "/Abs/" + "cube" + ".ab";
        AssetBundle ab;
        using (UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(url))
        {
            //yield return request.SendWebRequest();
            request.SendWebRequest();
            while (!request.isDone)
            {
                Debug.Log(request.downloadProgress);
                //textProgress.text = (request.downloadProgress * 100).ToString("F0") + "%";
                yield return null;
            }
            if (request.isDone)
            {
                Debug.Log(100);
                //textProgress.text = 100 + "%";
            }
            ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
            if (ab == null)
            {
                Debug.LogError("AB包为空");
                yield break;
            }

        }
        GameObject ga = ab.LoadAsset<GameObject>("Assets/Prefabs/cube.prefab");//加载出来
        Instantiate<GameObject>(ga);//实例化出来

        //Debug.Log(ga.name);
        //ab.Unload(false); 
        Debug.Log("成功");
        yield break;
    }

    public void LoadScene(string url)
    {
        StartCoroutine(DownloadScene(url));
    }
    IEnumerator DownloadScene(string url)
    {

        //ab包的地址
        //string url = Application.streamingAssetsPath + "/Abs/" + "samplescene";

        //方式一
        //AssetBundle ab;
        //using (UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(url))
        //{
        //    //yield return request.SendWebRequest();
        //    request.SendWebRequest();
        //    while (!request.isDone)
        //    {
        //        Debug.Log(request.downloadProgress);
        //        //textProgress.text = (request.downloadProgress * 100).ToString("F0") + "%";
        //        yield return null;
        //    }
        //    if (request.isDone)
        //    {
        //        Debug.Log(100);
        //        //textProgress.text = 100 + "%";
        //    }
        //    ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
        //    if (ab == null)
        //    {
        //        Debug.LogError("AB包为空");
        //        yield break;
        //    }
        //    string[] s = ab.GetAllScenePaths();
        //    SceneManager.LoadScene(s[0], LoadSceneMode.Single);
        //}

        //方式二
        myLoadedAssetBundle = AssetBundle.LoadFromFile(url);
        scenePaths = myLoadedAssetBundle.GetAllScenePaths();
        SceneManager.LoadScene(scenePaths[0], LoadSceneMode.Single);

        Debug.Log("成功");
        yield break;
    }
    private AssetBundle myLoadedAssetBundle;
    private string[] scenePaths;
}


这里面的加载场景有两种方式,但是最关键、核心的就是这句代码
scenePaths = myLoadedAssetBundle.GetAllScenePaths();

以上就是打包和加载了
但是这样的打包存在一定的局限性,不太建议使用这种方式。还有一种方式就是使用官方的AssetBundleBrowser来进行打包和加载(也是个人比较推荐的)。

实现打AB包方法二:

1、去PackageManager里面下载Asset Bundle Browser;
2、打开Asset Bundle Browser窗口;
在这里插入图片描述
3、把资源拖进去
在这里插入图片描述
(这里报感叹号弄成依赖资源就可以去掉了,当然也可以不管)
在这里插入图片描述
然后build根据个人需求修改就可以打包了
在这里插入图片描述
至此,打包结束。

然后就是加载资源:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;

public class DemoLoadBundle : MonoBehaviour
{
    public string bundleName = "dogpbr";//预制体ab的名字
    public string assetName = "dogpbr";//加载到场景中这个物体的名字

    private void Start()
    {
        DontDestroyOnLoad(gameObject);

        LoadDependencies();//加载依赖资源

        LoadBundleScene();//加载场景
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Q))
        {
            InstantiateBundlePrefab();//加载预制体生成到场景中
        }
    }

    /// <summary>
    /// 加载所有依赖资源(这里记录的只是单个场景和单个预制体的演示)
    /// </summary>
    void LoadDependencies()
    {
        //AssetBundleManifest 记录着所有资源的依赖信息
        AssetBundle assetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/StandaloneWindows");
        AssetBundleManifest manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

        //加载预制体的依赖包
        string[] dependenciesPrefab = manifest.GetAllDependencies(bundleName);
        foreach (var dependencie in dependenciesPrefab)
        {
            var dependencieAsync = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + dependencie);
        }

        //加载场景的依赖包
        string[] dependencieScene = manifest.GetAllDependencies(sceneName);
        foreach (var dependencie in dependencieScene)
        {
            var dependencieAsync = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + dependencie);
        }
    }
    /// <summary>
    /// 加载ab包的预制体(单个)
    /// </summary>
    private void InstantiateBundlePrefab()
    {
        AssetBundle asset = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + bundleName);
        var asset_go = asset.LoadAsset<GameObject>(assetName);
        Instantiate(asset_go);
    }

    public string sceneName = "abtestscene";//场景打包出来的名字
    #region 方式一
    /// <summary>
    /// 加载ab包的场景(单个)
    /// 注:加载场景的时候可能会出现一个问题,那就是场景里面存在一个ab包的预制体,但你再去加载这个预制体就会报错。(解决办法就是把你场景里面的那个预制体删掉就可以了)
    /// </summary>
    IEnumerator LoadABScene()
    {
        AssetBundle ab;
        using (UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(""))
        {
            //yield return request.SendWebRequest();
            request.SendWebRequest();
            while (!request.isDone)
            {
                Debug.Log(request.downloadProgress);
                //textProgress.text = (request.downloadProgress * 100).ToString("F0") + "%";
                yield return null;
            }
            if (request.isDone)
            {
                Debug.Log(100);
                //textProgress.text = 100 + "%";
            }
            ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
            if (ab == null)
            {
                Debug.LogError("AB包为空");
                yield break;
            }
            string[] s = ab.GetAllScenePaths();
            SceneManager.LoadScene(s[0], LoadSceneMode.Single);
        }
    }
    #endregion

    #region 方式二
    /// <summary>
    /// 加载ab包的场景(单个)
    /// 注:加载场景的时候可能会出现一个问题,那就是场景里面存在一个ab包的预制体,但你再去加载这个预制体就会报错。(解决办法就是把你场景里面的那个预制体删掉就可以了)
    /// </summary>
    private void LoadBundleScene()
    {
        myLoadedAssetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + sceneName);
        scenePaths = myLoadedAssetBundle.GetAllScenePaths();
        SceneManager.LoadScene(scenePaths[0], LoadSceneMode.Single);
    }
    private AssetBundle myLoadedAssetBundle;
    private string[] scenePaths;
    #endregion
}

以上就是一整套的打包和加载了。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-07-16 11:38:06  更:2021-07-16 11:39:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:24:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码