AssetsBundle资源包的打包和加载

2023-11-02

如何打Assetsbundle资源包呢

这样

using UnityEditor;
using UnityEngine;

public class BuildAssetBundle
{
    /// <summary>
    /// 点击后,所有设置了AssetBundle名称的资源会被 分单个打包出来
    /// </summary>
    [MenuItem("AssetBundle/Build (Single)")]
    static void Build_AssetBundle()
    {
        BuildPipeline.BuildAssetBundles(Application.dataPath + "/Test_AssetBundle", BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);
        //如果你的ab包是给anidrod用的那就用下面这句
        //BuildPipeline.BuildAssetBundles(Application.dataPath + "/StreamingAssets", BuildAssetBundleOptions.None, BuildTarget.Android);
        //刷新
        AssetDatabase.Refresh();
    }

    /// <summary>
    /// 选择的资源合在一起被打包出来
    /// </summary>
    [MenuItem("AssetBundle/Build (Collection)")]
    static void Build_AssetBundle_Collection()
    {
        AssetBundleBuild[] buildMap = new AssetBundleBuild[1];
        //打包出来的资源包名字
        buildMap[0].assetBundleName = "enemybundle";

        //在Project视图中,选择要打包的对象  
        Object[] selects = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
        string[] enemyAsset = new string[selects.Length];
        for (int i = 0; i < selects.Length; i++)
        {
            //获得选择 对象的路径
            enemyAsset[i] = AssetDatabase.GetAssetPath(selects[i]);
        }
        buildMap[0].assetNames = enemyAsset;

        BuildPipeline.BuildAssetBundles(Application.dataPath + "/Test_AssetBundle", buildMap, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);
        //打Anidrod包
        //BuildPipeline.BuildAssetBundles(Application.dataPath+ "StreamingAssets", buildMap, BuildAssetBundleOptions.None, BuildTarget.Android);
        //刷新
        AssetDatabase.Refresh();
    }
}

使用代码前记得在assets文件夹下创建文件夹“Test_AssetBundle”,为打包提供路径

那么如何去使用assetsbundle资源包呢

这样

public GameObject _Canvas;//定义物体

 IEnumerator GetModel(int num, string path, int sum)
    {
        string endPath = @"file://" + Application.dataPath + "/Test_AssetBundle/interface01";
        //anidrod平台加载streamingAssets文件夹下的ab包资源用下面这句
        //string endPath = Application.streamingAssetsPath + "/interface02";
        //Android平台加载/storage/emulated/0/(SD卡)下的资源用这种格式
        //string endPath= "file://" + path
        Debug.Log(endPath);
        WWW www = new WWW(endPath);//加载
        yield return www;
        AssetBundle bundle = www.assetBundle;
        //资源加载 
        //加载的是打包到资源包里面,每个资源的名字
        Instantiate(bundle.LoadAsset("Panel1.prefab"),_Canvas.transform);
        //Instantiate(bundle.LoadAsset("Sphere.prefab"));
        //Instantiate(bundle.LoadAsset("Capsule.prefab"));

        //资源加载完毕后记得Unload,不然再次加载资源的时候无法加载
        yield return new WaitForSeconds(6);
        bundle.Unload(false);
        //GameObject Obj = (GameObject)Instantiate(bundle.mainAsset);
        //Obj.transform.SetParent(this.transform);
    }

解释一下,因为我加载的是一个panel,是个UI,需要放在canvas下,所以在这里呢,

Instantiate(bundle.LoadAsset("Panel1.prefab"),_Canvas.transform);

我直接在加载时就把指定资源"Panel1.prefab"给了"_Canvas"作为子物体。

怎么卸载资源

在项目中你可能只是加载一遍就不再加载了,也可能你要用到多个不同的资源,需要加载这个再去加载那个,重复加载,这个时候如果不及时的对bundle资源进行卸载,你的设备就会越来越卡顿,程序崩溃,软件闪退。

AssetBundle的卸载(抄来的)

如果说AssetBundle真的有什么容易出问题的地方,那恐怕就是卸载了。

在这里只说最常用的这个卸载方法吧:

public void Unload(bool unloadAllLoadedObjects);

一个被加载过的AssetBundle可以通过调用Unload来卸载这个Bundle下所有的Asset。但是调用这个函数时传入的参数对卸载结果影响甚大。

Unity官方对这个函数的讲解非常详细,配图也非常直观,因此我只是简单总结一下。

相同点:

无论传入参数为 true 或是 false,调用Unload都可以Destroy当前AssetBundle对象,释放之前从AssetBundle文件中的Header部分所获取的信息。当然,被释放的AssetBundle对象无法再使用诸如LoadAsset、LoadAllAssets等函数加载资源。

不同点:

unloadAllLoadedObjects == true:

不仅Destroy了AssetBundle这个对象,而且这个AssetBundle下包含的所有对象,只要实例化了,有一个算一个,统统释放掉。

感觉就像

foreach(Object asset in assets)

if(asset != null)

delete asset;

asset = null;

比如你通过ab.LoadAsset(apple)后,将apple设置给go_0的一个Renderer,如果这时候ab.Unload(true),那go_0就傻了,咋回事儿啊,图咋没了呢?WTF啊。

它的好处是:不会有重复资源问题的情况发生,每次都处理的干干净净。

unloadAllLoadedObjects == false:

仅仅Destroy了AssetBundle这个对象,但是并没有释放这个AssetBundle下的任何Asset,因此如果有对象引用了这些Asset,也不会有问题。

它的风险(代价)是:下次再Load这个AssetBundle,并且通过这个AssetBundle重新读取了这个Asset,会在内存中重新创建一份,这样如果之前的Asset没有被释放,那么现在内存中就有两份Asset了。

这种情况如果频繁发生,便意味着内存中有很多资源将“不受控制”,容易引发内存占用过高的问题,而释放这种不受控的资源,仅有两种方式:

1、当没有对象引用到这些不受控资源时,每次调用Resources.UnloadUnusedAssets,回收之。

2、加载场景时,如果加载模式没有设置为LoadSceneMode.Additive,则会自动调用Resources.UnloadUnusedAssets。

好了,兄弟资源卸载学会了吧。
没有的话可以到这看看更详细的分析
http://blog.sina.com.cn/s/blog_c3e21e750102yfng.html
加油,你很棒~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

AssetsBundle资源包的打包和加载 的相关文章

  • wsl2安装及相关编程环境配置

    wsl2的安装及相关环境配置 1 设置 gt 更新和安全 gt 开发者选项 gt 开发人员模式 2 设置 gt 应用 gt 应用和功能 gt 程序和功能 gt 程序和功能 gt 启用或关闭windows功能 gt 适用于linux的wind

随机推荐

  • 编程训练————岛屿数量(C++)

    岛屿数量 题目描述 主要思想 深度优先搜索 广度优先搜索 代码实现 深度优先搜索 广度优先搜索 题目描述 给你一个由 1 陆地 和 0 水 组成的的二维网格 请你计算网格中岛屿的数量 岛屿总是被水包围 并且每座岛屿只能由水平方向或竖直方向上
  • 如何升级numpy的版本

    嗯 如何升级numpy的版本 这是个很火的问题 解决方案如下 在命令下输入pip install U numpy 就可以升级numpy包了 pip install upgrade numpy 这样也可以
  • 统计二叉树中度为1的节点,层序遍历实现

    include
  • 分布式高可靠:负载均衡

    分布式高可靠 负载均衡 前言 什么是负载均衡 服务请求的负载均衡方法 轮询策略 顺序轮询 加权轮询 随机策略 哈希和一致性哈希策略 对比分析 知识扩展 如果要考虑请求所需资源不同的话 应该如何设计负载均衡策略呢 总结 前言 分布式可靠性相关
  • chrome浏览器安装右键翻译插件

    平常打开网页查看相关文章的时候 遇到一些不会的英文单词 可能第一反应是复制英文单词到百度翻译里面 下面为介绍一种直接右键选中英文单词 实现在线翻译的插件 这边用到的是 划词翻译 插件 安装步骤如下 第一步 下载扩展程序插件 链接 https
  • 深入JVM - 实例详解invoke相关操作码

    Java虚拟机规范中有一个章节专门列出了操作码助记符 对应的链接为 Java Virtual Machine Specification Chapter 7 Opcode Mnemonics by Opcode 其中 方法调用相关的操作码为
  • 毕业设计 基于Arduino的肺活量计

    0 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕设题目缺少创新和亮点 往往达不到毕业答辩的要求 这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求 为了大家能够顺利以及最少的精力通过毕设 学长分享优质毕业设计项
  • 编程语言Java与c#的区别浅谈

    Java和c 都是编程的语言 它们是两个不同方向的两种语言 它们到底有什么区别呢 现在我给大家介绍一下 首先 我给大家说说他们的相同点吧 它们都是面向对象的语言 也就是说 它们都能够实现面向对象的思想 封装 继承 多态 下面给大家介绍一下它
  • NGINX源码之:listen和server_name命令与listening监听创建

    在http块的server块解析中 通过解析listen和server name命令配置 完成端口监听的初始化 虚拟主机配置关联 实现从host port到虚拟主机的映射关系 在进入解析源码之前 先来看看server块集中配置 server
  • html如何给3种渐变色,css中颜色渐变的实现(三种方式)

    本篇文章给大家带来的内容是关于css中颜色渐变的实现 三种方式 有一定的参考价值 有需要的朋友可以参考一下 希望对你有所帮助 注意IE9及之前的版本不支持渐变 Safari要加 webkit 的前缀 Opera要加 o 的前缀 Firefo
  • explicit关键字的作用及其用法

    一 explicit作用 在C 中 explicit关键字用来修饰类的构造函数 被修饰的构造函数的类 不能发生相应的隐式类型转换 只能以显示的方式进行类型转换 这个关键字只能用在类内部的构造函数声明上 而不能用在类外部的函数定义上 它的作用
  • vue后台返回二维码展示在前端页面,复制二维码到剪贴板

    1 二维码渲染 vue请求 后端返回二维码 在请求时加上 responseType blob export function getQrCode query return request url xx method get params q
  • 单点登录CAS学习(二):使用IDEA搭建cas-overlay-5.3工程

    上一篇对于单点登陆进行了初步了解 我们做单点登录应用的时候 会有两个场景 单点登录的服务端 单点登录的客户端 指各个应用系统 从本篇开始的系列文章将分别介绍服务端的工程如何搭建 客户端如何改造以适用于单点登录 首先从服务端开始 我们往往需要
  • ElasticSearch集群管理(VMware)

    一 集群结构 ES通常以集群方式工作 这样做不仅能够提高 ES的搜索能力还可以处理大数据搜索的能力 同时也增加了系统的 容错能力及高可用 下图是ES集群结构的示意图 此处的设置为 每个主分片有两个副本 如果某个节点挂了也不怕 比如节点1挂了
  • 操作系统学习(十一)处理机调度

    一 知识总览 调度 按某种规则来决定处理这些任务的顺序 多道程序系统中 进程的数目往往多于处理机的数目 按照一定的算法从进程就绪队列中选择一个进程将处理机分配给他 以实现进程的并发执行 二 高级调度 作业调度 作业 用户在一次解题或一个事务
  • 计算机单位换算

    一 计算机容量单位 容量单位 字节 B gt 千字节 KB gt 兆字节 MB gt 吉字节 GB gt TB gt PB gt EB ZB YB NB DB等 注 Byte就是B也就是字节 KB是千字节 MB是兆 GB是千兆 TB是千千兆
  • jvisualvm监控tomcat

    1 修改Tomcat的catalina sh文件 修改tomcat的bin目录下的 catalina sh文件 搜索 JAVA OPTS 在引号中添加参数 Dcom sun management jmxremote port 10086 D
  • 设计RandomPool结构

    详情参看 程序员代码面试指南 P474 package com gxu dawnlab algorithm5 import java util HashMap 设计RandomPool结构 author junbin 2019年7月1日 p
  • 手动添加本地路由表并用Quagga+ospf通知其它路由

    文章目录 参考文章 一 路由设置 1 参数说明 2 查询设置 二 动态路由的设置 实验 参考文章 Linux下使用Quagga搭建软路由 OSPFv2学习 鳥哥的 Linux 私房菜 一 路由设置 1 参数说明 root anzye rou
  • AssetsBundle资源包的打包和加载

    如何打Assetsbundle资源包呢 这样 using UnityEditor using UnityEngine public class BuildAssetBundle