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 包集

有一点需要注意:CreateAssetBundle_ZH 脚本需要安置在Asset 下 Editor文件夹下
              不然无法正确执行

请添加图片描述

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

/// <summary>
/// 菜单编辑 按钮点击
/// </summary>


//[CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/SpawnManagerScriptableObject", order = 1)]
public class CreateAssetBundle_ZH : MonoBehaviour //ScriptableObject
{
    //菜单栏 Button 创建
    [MenuItem("AssetBundles/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        //AssetBundle 存储路径
        string _AssetBundleDirectory = Application.streamingAssetsPath + "//AssetBundles";//Application.dataPath + "/Resources";

        //IO 构建
        if (!Directory.Exists(_AssetBundleDirectory))
        {
            Directory.CreateDirectory(_AssetBundleDirectory);
        }


        //构建编辑中指定的所有资产包 变量( 构建地址、 资产包构建选项、目标构建平台)//ChunkBasedCompression
        BuildPipeline.BuildAssetBundles(_AssetBundleDirectory, BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows64);

#if UNITY_EDITOR

        //资源刷新
        AssetDatabase.Refresh();

#endif

    }
}

正确放置之后就需要对你要使用的资源进行分包处理了
比如我这个:我对当前 Cube 把它放在了 model 里面这个AB包集里   
		   AB包集名字 是自己取得 如果你没有就自己 New 一个
注意:如果你要使用的资源没有赋予 AB包集的话 是没有办法生成AssetBundle 文件的

请添加图片描述

点击菜单栏 AssetBundles按钮下的Build AssetBundles 按钮就可以生成你自己的AssetBundle文件了

请添加图片描述

AssetBundle 基础功能

AssetBundle 加载:需要注意AB 包加载需要填写对的路径以及包集名字(小写)
						  正确加载 AB 包集后可以使用 LoadAsset() 方法加载当前包集中的具体资源
						  注意拿到具体资源后需要实例化 不然你就只是拿到
						  当前 AB 包集使用完毕之后注意 卸载 不然会报错
						  因为 AB 包的特性就是无法重复加载
 AssetBundle 包集

请添加图片描述

AssetBundle.LoadAsset() 默认返回值是Object 类型

请添加图片描述

这个就是主包中固定文件里的内容:里面包含了各个 AB 包集 的依赖关系

 //主包中固定文件的标准写法
AssetBundleManifest _AssetBundleManifest = _AssetBundleMain.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

请添加图片描述

AssetBundle 没有依赖项 加载

 	/// <summary>
    /// AssetBundle 没有依赖项的加载
    /// </summary>
    public void LoadAssetBundle()
    {
        //AB 包集加载  LoadFromFile方法里面的参数是 指定到文件的详细路径
        AssetBundle _AssetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/AssetBundles/"+ "model");

         //加载 AssetBundle 包体中的资源
        //使用名字加载 可能会出现同名但是资源类型不同的情况
        //注意加载 资源名称是根据填写的名字  全部都是小写
        //AssetBundle 无法重复加载 否则报空
        //两种加载方式  交易使用第二种 带指定类型的因为可以避免 加载资源时 同名不同类型的文件
        //但是也要看具体情况具体使用  随君意
        GameObject _Gam = _AssetBundle.LoadAsset<GameObject>("SphereModel") ;

        GameObject _Gam02 = _AssetBundle.LoadAsset("CubeModle", typeof(GameObject)) as GameObject;

        //实例化 
        Instantiate(_Gam);
        Instantiate(_Gam02);

        //AB 包集卸载       
        //false 只卸载AB 包集 但是不卸载资源
        //true 卸载AB 包集 同时也卸载资源
        //避免重复加载报空
        _AssetBundle.Unload(false);

    }

AssetBundle 没有依赖项 异步加载

/// <summary>
    /// 异步加载 AssetBundle
    /// </summary>
    /// <param AB包集 名字="_AssetBundleName"></param>
    /// <param AB包集中资源名字="_PrefabName"></param>
    /// <returns></returns>
    public IEnumerator  LoadAssetBundle(string _AssetBundleName,string _PrefabName)
    {
        //加载 AB集
        AssetBundleCreateRequest _AssetBundleCreateRequest = AssetBundle.LoadFromFileAsync(Application.streamingAssetsPath + "/AssetBundles/" + _AssetBundleName);
        //等待返回
        yield return _AssetBundleCreateRequest;

        //资源加载
        AssetBundleRequest _Abr = _AssetBundleCreateRequest.assetBundle.LoadAssetAsync(_PrefabName,typeof(GameObject));

        //默认类型为 Object 所以需要转换一下
        GameObject _Gam = _Abr.asset as GameObject;

        Instantiate(_Gam);

        //卸载所有当前加载的资源包 
        //false 只卸载AB 包集 但是不卸载资源
        //true 卸载AB 包集 同时也卸载资源
        //避免重复加载报空
        AssetBundle.UnloadAllAssetBundles(false);

        yield return null;
    }

AssetBundle 有依赖项 加载

/// <summary>
    /// AB包集 资源依赖
    /// </summary>
    /// <param 主包名字="_AssetBundlesPathName"></param>
    /// <param AB包子集="_AssetBundlesName"></param>
    /// <param 预制体 名字="_PrefabName"></param>
    public void LoadAssetBundleDepend(string _AssetBundlesPathName, string _AssetBundlesName, string _PrefabName)
    {
        //加载主包
        AssetBundle _AssetBundleMain = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/AssetBundles/" + _AssetBundlesPathName);


        //加载主包中的固定文件
        AssetBundleManifest _AssetBundleManifest = _AssetBundleMain.LoadAsset<AssetBundleManifest>("AssetBundleManifest");


        //从固定文件中得到依赖信息
        //得到你想要知道 当前AB包集中的所有依赖
        string[] _DependStr = _AssetBundleManifest.GetAllDependencies(_AssetBundlesName);

        //如果有依赖包的话
        if (_DependStr.Length > 0)
        {

            AssetBundle _NewAssetBundle = null;
            for (int j = 0; j < _DependStr.Length; j++)
            {
                //依赖包加载
                _NewAssetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/AssetBundles/" + _DependStr[j]);
            }

            //如果 AB 包集不为空
            if (_NewAssetBundle != null)
            {
                //AB包 子级资源加载
                AssetBundle _NewAssetBundleSubset;
                _NewAssetBundleSubset = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/AssetBundles/" + _AssetBundlesName);

                //GameObject _Gam = _NewAssetBundleSubset.LoadAsset<GameObject>(_PrefabName);
                GameObject _Gam = _NewAssetBundleSubset.LoadAsset(_PrefabName, typeof(GameObject)) as GameObject;

                Instantiate(_Gam);
            }
        }
        else
        {
            //如果没有依赖包就正常加载
            AssetBundle _NewAssetBundleSubset;
            _NewAssetBundleSubset = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/AssetBundles/" + _AssetBundlesName);

            //资源加载
            //GameObject _Gam = _NewAssetBundleSubset.LoadAsset<GameObject>(_PrefabName);
            GameObject _Gam = _NewAssetBundleSubset.LoadAsset(_PrefabName, typeof(GameObject)) as GameObject;

            Instantiate(_Gam);
        }
    }

AssetBundle 卸载


		//两种方法

        //AB 当前包集卸载       
        //false 只卸载当前AB 包集 但是不卸载资源
        //true 卸载当前AB 包集 同时也卸载资源
        //_AssetBundle 是当前加载的 AB 包集
        _AssetBundle.Unload(false);
   
        //卸载所有当前加载的资源包 
        //false 只卸载所有AB 包集 但是不卸载资源
        //true 卸载所有AB 包集 同时也卸载资源
        AssetBundle.UnloadAllAssetBundles(false);
        

AssetBundle 包管理器


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

/// <summary>
/// AssetBundle 包管理器
/// </summary>
public class AssetBundleManager_ZH : MonoBehaviour
{

    //单例
    public static AssetBundleManager_ZH _AssetBundleManager;

    //AssetBundle 主包
    private AssetBundle _AssetBundleMain = null;

    //依赖包配置文件
    private AssetBundleManifest _AssetBundleManifest = null;



    //AB包集字典 存储已经加载的AB包
    //key AB 包名字 value AB包
    private Dictionary<string, AssetBundle> _AssetBundleDic = new Dictionary<string, AssetBundle>();

    /// <summary>
    /// AssetBundle主包 加载路径
    /// </summary>
    public string _AssetBundlePath 
    { 
        get
        {
           return Application.streamingAssetsPath + "/AssetBundles/";
        }
        set 
        {
            _AssetBundlePath = value;
        } 
    }

    /// <summary>
    /// 主包名
    /// </summary>
    public string _AssetBundleMainName
    {
        get
        {
            return "AssetBundles";
        }
        set
        {
            _AssetBundleMainName = value;
        }
    }

   private void Awake()
    {
        _AssetBundleManager = this;
    }


    #region AssetBundle 资源同步加载

    /// <summary>
    /// 同步加载 不指定类型
    /// </summary>
    /// <param 需要加载的AB 包名字="_AssetBundleName"></param>
    /// <param 需要加载的资源名字="_ResName"></param>
    /// <returns></returns>
    public Object LoadAssetBundleSync(string _AssetBundleName, string _ResName)
    {

        LoadAB(_AssetBundleName);

        Object _AssetBundleObject = _AssetBundleDic[_AssetBundleName].LoadAsset(_ResName);

        //实例化
        if (_AssetBundleObject as GameObject)
        {
            return Instantiate(_AssetBundleObject);
        }
        else
        {
            //加载 当前 使用资源 AB 包(_AssetBundleName)名为  _ResName 的资源
            return _AssetBundleObject;
        }
    }


    /// <summary>
    /// 同步加载 指定类型
    /// 方便加载资源时 同名不同类型的文件
    /// </summary>
    /// <param 需要加载的AB 包名字="_AssetBundleName"></param>
    /// <param 需要加载的资源名字="_ResName"></param>
    /// <param 指定的类型="_Type"></param>
    /// <returns></returns>
    public Object LoadAssetBundleSync(string _AssetBundleName, string _ResName, System.Type _Type)
    {
        LoadAB(_AssetBundleName);

        Object _AssetBundleObject = _AssetBundleDic[_AssetBundleName].LoadAsset(_ResName, _Type);

        //实例化
        if (_AssetBundleObject as GameObject)
        {
            return Instantiate(_AssetBundleObject);
        }
        else
        {
            //加载 当前 使用资源 AB 包(_AssetBundleName)名为  _ResName 的资源
            return _AssetBundleObject;
        }
    }


    /// <summary>
    /// 同步加载 不指定类型 泛型加载
    /// 方便加载资源时 同名不同类型的文件
    /// </summary>
    /// <typeparam 返回类型="T"></typeparam>
    /// <param 需要加载的AB 包名字="_AssetBundleName"></param>
    /// <param 需要加载的资源名字="_ResName"></param>
    /// <returns></returns>
    public T LoadAssetBundleSync<T>(string _AssetBundleName, string _ResName) where T : Object
    {
        LoadAB(_AssetBundleName);

        T _AssetBundleObject = _AssetBundleDic[_AssetBundleName].LoadAsset<T>(_ResName);

        //实例化
        if (_AssetBundleObject as GameObject)
        {
            return Instantiate(_AssetBundleObject);
        }
        else
        {
            //加载 当前 使用资源 AB 包(_AssetBundleName)名为  _ResName 的资源
            return _AssetBundleObject;
        }
    }

    #endregion



    #region AssetBundle 资源异步加载

    /// <summary>
    /// 根据名字异步加载资源
    /// </summary>
    /// <param 需要加载的AB 包名字="_AssetBundleName"></param>
    /// <param 需要加载的资源名字="_ResName"></param>
    /// <param 委托="_CallBack"></param>
    public void LoadResAsync(string _AssetBundleName, string _ResName,UnityAction<Object> _CallBack)
    {
        StartCoroutine(ReallyLoadResAsync(_AssetBundleName, _ResName, _CallBack));
    }
    /// <summary>
    ///异步资源加载
    /// </summary>
    /// <param  需要加载的AB 包名字="_AssetBundleName"></param>
    /// <param 需要加载的资源名字="_ResName"></param>
    /// <param 委托="_CallBack"></param>
    private IEnumerator ReallyLoadResAsync(string _AssetBundleName, string _ResName, UnityAction<Object> _CallBack)
    {
        LoadAB(_AssetBundleName);

        AssetBundleRequest _ABR  = _AssetBundleDic[_AssetBundleName].LoadAssetAsync(_ResName);


        yield return _ABR;


        //异步加载结束后 通过委托 传递资源给外部
        //实例化
        if (_ABR.asset as GameObject)
        {
            _CallBack(Instantiate(_ABR.asset));
        }
        else
        {
            //加载 当前 使用资源 AB 包(_AssetBundleName)名为  _ResName 的资源
            _CallBack(_ABR.asset);
        }
    }



    /// <summary>
    /// 异步加载 指定类型
    /// 方便加载资源时 同名不同类型的文件
    /// </summary>
    /// <param 需要加载的AB 包名字="_AssetBundleName"></param>
    /// <param 需要加载的资源名字="_ResName"></param>
    /// <param 指定的类型="_Type"></param>
    /// <param 委托="_CallBack"></param>
    public void LoadResAsync(string _AssetBundleName, string _ResName, System.Type _Type,UnityAction<Object> _CallBack)
    {
        StartCoroutine(ReallyLoadResAsync(_AssetBundleName, _ResName, _Type, _CallBack));
    }
    /// <summary>
    /// 异步资源加载 指定类型
    /// </summary>
    /// <param 需要加载的AB 包名字="_AssetBundleName"></param>
    /// <param 需要加载的资源名字="_ResName"></param>
    /// <param 指定的类型="_Type"></param>
    /// <param 委托="_CallBack"></param>
    private IEnumerator ReallyLoadResAsync(string _AssetBundleName, string _ResName, System.Type _Type, UnityAction<Object> _CallBack)
    {
        LoadAB(_AssetBundleName);

        AssetBundleRequest _ABR = _AssetBundleDic[_AssetBundleName].LoadAssetAsync(_ResName, _Type);


        yield return _ABR;


        //异步加载结束后 通过委托 传递资源给外部
        //实例化
        if (_ABR.asset as GameObject)
        {
            _CallBack(Instantiate(_ABR.asset));
        }
        else
        {
            //加载 当前 使用资源 AB 包(_AssetBundleName)名为  _ResName 的资源
            _CallBack(_ABR.asset);
        }
    }


    /// <summary>
    /// 异步加载 不指定类型 泛型加载
    /// 方便加载资源时 同名不同类型的文件
    /// </summary>
    /// <typeparam 返回类型="T"></typeparam>
    /// <param 需要加载的AB 包名字="_AssetBundleName"></param>
    /// <param 需要加载的资源名字="_ResName"></param>
    /// <returns></returns>
    public void LoadResAsync<T>(string _AssetBundleName, string _ResName, UnityAction<T> _CallBack)where T:Object
    {
        StartCoroutine(ReallyLoadResAsync<T>(_AssetBundleName, _ResName, _CallBack));
    }
    /// <summary>
    /// 异步加载 不指定类型 泛型加载
    /// 方便加载资源时 同名不同类型的文件
    /// </summary>
    /// <typeparam 返回类型="T"></typeparam>
    /// <param 需要加载的AB 包名字="_AssetBundleName"></param>
    /// <param 需要加载的资源名字="_ResName"></param>
    /// <returns></returns>
    private IEnumerator ReallyLoadResAsync<T>(string _AssetBundleName, string _ResName, UnityAction<T> _CallBack) where T : Object
    {
        LoadAB(_AssetBundleName);

        AssetBundleRequest _ABR = _AssetBundleDic[_AssetBundleName].LoadAssetAsync(_ResName);


        yield return _ABR;


        //异步加载结束后 通过委托 传递资源给外部
        //实例化
        if (_ABR.asset as GameObject)
        {
            _CallBack(Instantiate(_ABR.asset)as T);
        }
        else
        {
            //加载 当前 使用资源 AB 包(_AssetBundleName)名为  _ResName 的资源
            _CallBack(_ABR.asset as T);
        }
    }

    #endregion



    /// <summary>
    /// 主包以及依赖包加载
    /// </summary>
    /// <param 需要加载的AB 包名字="_AssetBundleName"></param>
    public void LoadAB(string _AssetBundleName)
    {
        //AssetBundle 主包加载
        if (_AssetBundleMain == null)
        {
            _AssetBundleMain = AssetBundle.LoadFromFile(_AssetBundlePath + _AssetBundleMainName);

            //依赖包加载
            _AssetBundleManifest = _AssetBundleMain.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
        }

        //从固定文件中得到依赖信息
        //得到你想要知道 当前AB包集中的所有依赖
        string[] _DependStr = _AssetBundleManifest.GetAllDependencies(_AssetBundleName);


        //如果有依赖包的话
        if (_DependStr.Length > 0)
        {
            //资源 AB 包
            AssetBundle _NewAssetBundleSubset;

            for (int i = 0; i < _DependStr.Length; i++)
            {
                //判断 AB 包是否加载过
                //如果没有加载过
                if (!_AssetBundleDic.ContainsKey(_DependStr[i]))
                {
                    //依赖包加载
                    _NewAssetBundleSubset = AssetBundle.LoadFromFile(_AssetBundlePath + _DependStr[i]);

                    //AB包 字典数据存储
                    _AssetBundleDic.Add(_DependStr[i], _NewAssetBundleSubset);
                }
            }

            //判断 AB 包是否加载过
            //如果没有加载过
            if (!_AssetBundleDic.ContainsKey(_AssetBundleName))
            {
                //使用资源 AB 包加载 并进行重新赋值
                _NewAssetBundleSubset = AssetBundle.LoadFromFile(_AssetBundlePath + _AssetBundleName);

                //AB包 字典数据存储
                _AssetBundleDic.Add(_AssetBundleName, _NewAssetBundleSubset);
            }
        }
    }


    /// <summary>
    /// 单个 AssetBundle 包 卸载
    /// </summary>
    /// <param name="_AssetBundleName"></param>
    public void UnLoadAssetBuindle(string _AssetBundleName)
    {
        //判断当前 AB包数据 字典是否存在 当前AB 包资源
        if (_AssetBundleDic.ContainsKey(_AssetBundleName))
        {
            //AB 包集卸载       
            //false 只卸载AB 包集 但是不卸载资源
            //true 卸载AB 包集 同时也卸载资源
            //避免重复加载报空
            _AssetBundleDic[_AssetBundleName].Unload(false);

            //移除 AB数据字典
            _AssetBundleDic.Remove(_AssetBundleName);
        }
    }

    /// <summary>
    ///  所有 AssetBundle 包 卸载
    /// </summary>
    /// <param name="_AssetBundleName"></param>
    public void UnLoadAllAssetBuindles()
    {
        //卸载所有当前加载的资源包 
        //false 只卸载AB 包集 但是不卸载资源
        //true 卸载AB 包集 同时也卸载资源
        //避免重复加载报空
        AssetBundle.UnloadAllAssetBundles(false);

        //AB数据字典 清空
        _AssetBundleDic.Clear();

        //AssetBundle 主包
        _AssetBundleMain = null;

        //依赖包配置文件
        _AssetBundleManifest = null;

        //AssetBundle主包 加载路径
        _AssetBundlePath = null;

        //主包名
        _AssetBundleMainName = null;
    }



    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Q))
        {
            //同步加载 不指定类型加载
            LoadAssetBundleSync("model", "CubeModle");
            //同步加载 指定类型加载
            LoadAssetBundleSync("model", "SphereModel",typeof(GameObject));
            //同步加载 不指定类型 泛型加载
            LoadAssetBundleSync<GameObject>("model", "CylinderModle");
        }

        if (Input.GetKeyDown(KeyCode.E))
        {
            //同步加载 不指定类型加载
            LoadResAsync("model", "CubeModle",(_Obj=> 
            {
                (_Obj as GameObject).transform.position = new Vector3((_Obj as GameObject).transform.position.x, 3, (_Obj as GameObject).transform.position.z);
            }));
            //同步加载 指定类型加载
            //同步加载 不指定类型加载
            LoadResAsync("model", "SphereModel",typeof(GameObject), (_Obj =>
            {
                (_Obj as GameObject).transform.position = new Vector3((_Obj as GameObject).transform.position.x, 3, (_Obj as GameObject).transform.position.z);
            }));
            //同步加载 不指定类型 泛型加载
            //同步加载 不指定类型加载
            LoadResAsync<GameObject>("model", "CylinderModle", (_Obj =>
            {
                _Obj .transform.position = new Vector3(_Obj.transform.position.x, 3, _Obj.transform.position.z);
            }));
        }
    }
}

搭载运行

脚本搭载

请添加图片描述

基础运行
点击两次也不会报错说明运行良好可以直接使用

请添加图片描述

请添加图片描述

暂时先这样吧,如果有时间的话就会更新,实在看不明白就留言,看到我会回复的。
路漫漫其修远兮,与君共勉。

  游戏开发 最新文章
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-08-21 15:47:34  更:2021-08-21 15:47:41 
 
开发: 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年5日历 -2024/5/4 9:49:47-

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