读取/加载 AssetBundle 资源的多种方式


本文提供全流程,中文翻译。

Chinar 坚持将简单的生活方式,带给世人!

(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例)


Chinar —— 心分享、心创新!

助力快速理解如何读取 AssetBundle 中的资源

为新手节省宝贵的时间,避免采坑!

Chinar 教程效果:



全文高清图片,点击即可放大观看 (很多人竟然不知道)


0

AssetBundle Description —— AssetBundle描述

AssetBundle 的具体定义网上诸多大神的解释很是细致,一搜一大片,在这里我都不再班门弄斧了

这里 Chinar 只简单说下为什么要用它
1. 如果所有的资源文件,全部打包到程序中,那么程序的安装包就会很大

AssetBundle 文件放在服务器上,用的时候再从服务器进行加载,所以这个包根本就不在程序当中
2. 那就是最主要的热更新了
发布软件后,开发者进行很小的一次更新,都需要重新打包发布

而对于用户来说,需要重新下载进行安装,无疑导致了用户体验不好。只要有更新,用户就重新安装程序

AssetBundle 技术,可以在用户重装软件的情况下,做到更改程序中的一些资源,设置

开发者可以实时的完成更新,应用到所有用户的客户端上,非常方便

那么 AssetBundle 打包后的资源,如何进行读取呢?

由于 AssetBundle 打包后的文件,是外部文件,我们的程序又是如何加载其中的资源的呢?

这里 Chinar 具体介绍 4 种 AssetBundle 文件的读取方式



不知道如何打包AssetBundle资源的? (请点击这里,了解打包流程)


1

Async Loading —— 内存加载-异步加载

从内存中加载

主要函数:AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path1))

我们如何将一个需要的资源打包到 AssetBundle 中呢?

为了便于测试我们是否加载了包中的资源内容,简单的创建了一个 UI Image 来展示效果

Hierarchy 层次面板结构如下





脚本如下:

using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.UI; /// <summary>
/// 异步加载 —— 从内存中加载 LoadFromMemory
/// </summary>
public class ChinarAsyncLoading : MonoBehaviour
{
private Image image; //场景中创建一个 UI Image元素为了测试 IEnumerator Start()
{
image = GameObject.Find("Image").GetComponent<Image>(); //动态获取UI上的组件
string path1 = "ChinarAssetBundles/globule.unity3d"; //资源包路径
string path2 = "ChinarAssetBundles/chinar/sprite.unity3d"; //子选项精灵图片文件路径
AssetBundleCreateRequest request1 = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path1)); //读取文件1请求
yield return request1; //返回1
AssetBundleCreateRequest request2 = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path2)); //读取文件2请求
yield return request2; //返回2
AssetBundle ab1 = request1.assetBundle; //资源1
AssetBundle ab2 = request2.assetBundle; //资源2
object sphereHead = ab1.LoadAsset("Sphere-Head"); //加载ab1包中的资源名为 Sphere-Head 文件的数据,返回Object对象 (这是一个预设物)
Instantiate((GameObject) sphereHead); //将对象,转为GameObject,实例化到场景中
object sprite = ab2.LoadAsset("Chinar1", typeof(Sprite)); //加载ab2包中的资源名为 Chianr1 文件的数据,并转为 Sprite类型,返回Object对象 (这是精灵图片)
image.sprite = (Sprite) sprite; //转为Sprite类型,给Image 赋值
}
}

运行后效果:


2

Sync Loading —— 内存加载-同步加载(无需协成)

从内存中加载

这种加载方式,无需使用协成,即可直接完成资源的加载

主要函数:AssetBundle.LoadFromMemory(File.ReadAllBytes(path1))



脚本如下:

using System.IO;
using UnityEngine;
using UnityEngine.UI; /// <summary>
/// 同步加载 —— 无需协成,从内存加载
/// </summary>
public class ChinarSyncLoading : MonoBehaviour
{
private Image image; //场景中创建一个 UI Image元素为了测试 void Start()
{
image = GameObject.Find("Image").GetComponent<Image>(); //动态获取UI上的组件
string path1 = "ChinarAssetBundles/globule.unity3d"; //资源包路径
string path2 = "ChinarAssetBundles/chinar/sprite.unity3d"; //子选项精灵图片文件路径
AssetBundle ab1 = AssetBundle.LoadFromMemory(File.ReadAllBytes(path1)); //资源1
AssetBundle ab2 = AssetBundle.LoadFromMemory(File.ReadAllBytes(path2)); //资源2
object sphereHead = ab1.LoadAsset("Sphere-Head"); //加载ab1包中的资源名为 Sphere-Head 文件的数据,返回Object对象 (这是一个预设物)
Instantiate((GameObject) sphereHead); //将对象,转为GameObject,实例化到场景中
object sprite = ab2.LoadAsset("Chinar1", typeof(Sprite)); //加载ab2包中的资源名为 Chianr1 文件的数据,并转为 Sprite类型,返回Object对象 (这是精灵图片)
image.sprite = (Sprite) sprite; //转为Sprite类型,给Image 赋值
}
}

运行后效果:


3

LoadFromFile ——本地加载

第二种加载方式,从本地加载资源

主要函数:AssetBundle.LoadFromMemory(File.ReadAllBytes(path1))



脚本如下:

using UnityEngine;
using UnityEngine.UI; /// <summary>
/// 同步加载 —— 无需协成,从本地加载
/// </summary>
public class ChinarFileLoading : MonoBehaviour
{
private Image image; //场景中创建一个 UI Image元素为了测试 void Start()
{
image = GameObject.Find("Image").GetComponent<Image>(); //动态获取UI上的组件
string path1 = "ChinarAssetBundles/globule.unity3d"; //资源包路径
string path2 = "ChinarAssetBundles/chinar/sprite.unity3d"; //子选项精灵图片文件路径
AssetBundle ab1 = AssetBundle.LoadFromFile(path1); //资源1:直接读出资源
AssetBundle ab2 = AssetBundle.LoadFromFile(path2); //资源2:直接读出资源
object sphereHead = ab1.LoadAsset("Sphere-Head"); //加载ab1包中的资源名为 Sphere-Head 文件的数据,返回Object对象 (这是一个预设物)
Instantiate((GameObject) sphereHead); //将对象,转为GameObject,实例化到场景中
object sprite = ab2.LoadAsset("Chinar1", typeof(Sprite)); //加载ab2包中的资源名为 Chianr1 文件的数据,并转为 Sprite类型,返回Object对象 (这是精灵图片)
image.sprite = (Sprite) sprite; //转为Sprite类型,给Image 赋值
}
}

运行后效果:与上边一致


4

LoadFromWWW ——本地/服务器加载

第三种加载方式,从本地 / 服务器 WWW 加载资源

主要函数:AssetBundle.LoadFromMemory(File.ReadAllBytes(path1))

注意:Chinar为没有服务器的朋友准备了测试资源

资源地址就在脚本中,注释写的很详细。如果连接不上,可能是网络问题,多连接几次即可

想要几百元就拥有自己的网站和服务器的话

请看最下方的服务器购买教程(不要忘记我的推广券哦,可以减钱抽奖!



脚本如下:

using System.Collections;
using System.Security.Policy;
using UnityEngine;
using UnityEngine.UI; /// <summary>
/// 网络服务器加载方式
/// </summary>
public class ChinarWwwLoading : MonoBehaviour
{
private Image image; //场景中创建一个 UI Image元素为了测试 IEnumerator Start()
{
image = GameObject.Find("Image").GetComponent<Image>(); //动态获取UI上的组件
string path1 = "file:C:/Users/Administrator/Desktop/Tutorial AssetBundle/ChinarAssetBundles/globule.unity3d"; //本地资源包路径
string path2 = "http://www.unity.kim/ChinarAssetBundles/chinar/sprite.unity3d"; //服务器上,存放的子选项精灵图片文件网络地址
while (Caching.ready == false) yield return null; //是否准备好
WWW www1 = WWW.LoadFromCacheOrDownload(@path1, 1); //从本地加载
WWW www2 = WWW.LoadFromCacheOrDownload(@path2, 1); //从服务器加载
yield return www2; //等待服务器加载完成,再向下执行
if (string.IsNullOrEmpty(www2.error) == false) //报空返回
{
Debug.Log(www2.error);
yield break;
}
AssetBundle ab1 = www1.assetBundle; //本地,资源包1,其中为预设物
AssetBundle ab2 = www2.assetBundle; //网络,资源包2,其中为Chinar上传好的图片,大家可以放心加载测试
object sphereHead = ab1.LoadAsset("Sphere-Head"); //加载ab1包中的资源名为 Sphere-Head 文件的数据,返回Object对象 (这是一个预设物)
Instantiate((GameObject)sphereHead); //将对象,转为GameObject,实例化到场景中
object sprite = ab2.LoadAsset("Chinar1", typeof(Sprite)); //加载ab2包中的资源名为 Chianr1 文件的数据,并转为 Sprite类型,返回Object对象 (这是精灵图片)
image.sprite = (Sprite)sprite; //转为Sprite类型,给Image 赋值
} //#region 第二种网络加载方式
//IEnumerator Start()
//{
// image = GameObject.Find("Image").GetComponent<Image>();
// string path1 = "file:C:/Users/Administrator/Desktop/Tutorial AssetBundle/ChinarAssetBundles/globule.unity3d"; //本地预设物资源包路径
// //(Chinar为没有自己服务器的准备的以下网络资源,直接加载即可)
// //如果想买个服务器,请看Chinar服务器购买教程,非常简便便宜(记得领券哦)
// string path2 = "http://www.unity.kim/ChinarAssetBundles/globule.unity3d"; //服务器上,存放的预设物路径(Chinar为没有自己服务器的准备的资源,直接加载即可)
// string path3 = "http://www.unity.kim/ChinarAssetBundles/chinar/sprite.unity3d"; //服务器上,存放的子选项精灵图片文件网络地址 // using (WWW www = new WWW(path3))
// {
// yield return www; //等待网络下载
// if (www.error != null) //如果错误信息不为空
// {
// print("网络错误"); //提示网络错误
// }
// else
// {
// AssetBundle bundle = www.assetBundle; //声明 bundle对象接收资源 // #region 1-网络预设物资源加载,实例化 // //object obj = bundle.LoadAsset("Sphere-Head"); //加载资源 返回一个Object对象 赋值给obj
// //Instantiate((GameObject)obj); // #endregion // #region 2-网络精灵图片1资源加载,实例化 // //object obj = bundle.LoadAsset(""Chinar1"", typeof(Sprite)); //加载资源 返回一个Object对象,转Sprite 赋值给obj
// //image.sprite = (Sprite)obj; // #endregion // #region 3-网络精灵图片2资源加载,实例化 // object obj = bundle.LoadAsset("Chinar青色", typeof(Sprite)); //加载资源 返回一个Object对象,转Sprite 赋值给obj
// image.sprite = (Sprite)obj;
// print(obj); // #endregion // bundle.Unload(false); //只卸载已经用过的
// }
// www.Dispose(); //释放资源
// }
//}
//#endregion }

运行后效果:与上边一致。但有些网络连接慢的时候,资源需要等待下载才显示


5

LoadWebServer ——从服务器网络加载

第四种加载方式,从服务器/网络上 Url 加载资源

注意:Chinar为没有服务器的朋友准备了测试资源

资源地址就在脚本中,注释写的很详细。如果连接不上,可能是网络问题,多连接几次即可

想要几百元就拥有自己的网站和服务器的话

请看最下方的服务器购买教程(不要忘记我的推广券哦,可以减钱抽奖!



脚本如下:

using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI; /// <summary>
/// Unity 新网络服务器加载AssetBundle方式
/// </summary>
public class ChinarWebServerLoading : MonoBehaviour
{
private Image image; //场景中创建一个 UI Image元素为了测试 IEnumerator Start()
{
image = GameObject.Find("Image").GetComponent<Image>(); //动态获取UI上的组件 const string url1 = @"http://www.unity.kim/ChinarAssetBundles/globule.unity3d"; //服务器地址,Chinar提供用于测试,大神勿黑!(存一个预设物:"Sphere-Head")
const string url2 = @"http://www.unity.kim/ChinarAssetBundles/chinar/sprite.unity3d"; //服务器上,存放的子选项精灵图片文件网络地址(存2张Sprite:"Chinar1"与“Chinar青色”)
UnityWebRequest request1 = UnityWebRequestAssetBundle.GetAssetBundle(url1); //Unity网络请求AssetBundle.获取资源(网络地址1)
UnityWebRequest request2 = UnityWebRequestAssetBundle.GetAssetBundle(url2); //传入地址2
yield return request1.SendWebRequest(); //发送Web请求1
yield return request2.SendWebRequest(); //发送web请求2
AssetBundle ab1 = DownloadHandlerAssetBundle.GetContent(request1); //下载资源委托,获取连接请求1,返回AssetBundle资源
AssetBundle ab2 = DownloadHandlerAssetBundle.GetContent(request2); //获取连接请求2,返回AssetBundle资源
object sphereHead = ab1.LoadAsset("Sphere-Head"); //加载 资源ab1中的名叫“Sphere-Head”的圆球
Instantiate((GameObject) sphereHead); //实例化出来
object obj = ab2.LoadAsset("Chinar青色", typeof(Sprite)); //加载资源 返回一个Object对象,转Sprite 赋值给obj
image.sprite = (Sprite) obj; //赋值给UiImage
//AssetBundle ab = ((DownloadHandlerAssetBundle)request3.downloadHandler).assetBundle; //另一种写法
}
}

运行后效果:有些网络连接慢的时候,资源需要等待下载才显示


支持

May Be —— 搞开发,总有一天要做的事!

拥有自己的服务器,无需再找攻略!

Chinar 提供一站式教程,闭眼式创建!

为新手节省宝贵时间,避免采坑!

先点击领取 —— 阿里全产品优惠券 (享受最低优惠)



1 —— 云服务器超全购买流程 (新手必备!)



2 —— 阿里ECS云服务器自定义配置 - 购买教程(新手必备!)



3—— Windows 服务器配置、运行、建站一条龙 !



4 —— Linux 服务器配置、运行、建站一条龙 !




" role="presentation">

技术交流群:806091680 ! Chinar 欢迎你的加入


END

本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究


对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com


对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址

Unity读取AssetBundle资源全教程(所有读取方式)的更多相关文章

  1. Unity打包/读取AssetBundle资源全教程

    Unity 资源AssetBundle打包 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar ...

  2. Unity 从StreamingAssets文件夹和PersistentData文件夹 保存读取AssetBundle资源

    项目中的资源一般我们打包成AssetBundle格式 方便我们加载和热更 而AssetBundle文件 一般保存在StreamingAssets文件夹或则PersistentData文件夹 首先我们看 ...

  3. C# 读取 Excel 最全最稳定的方式

    采用 NPOI 和 Epplus 方式读取Excel,因为之前测试NPOI的时候发现对于 .xlsx 格式的文件读取不是很友好,所以才结合了两个. 废话少说,直接上代码: public static ...

  4. (转)Unity3D移动平台动态读取外部文件全解析

    Unity3D移动平台动态读取外部文件全解析 c#语言规范 阅读目录 前言: 假如我想在editor里动态读取文件 移动平台的资源路径问题 移动平台读取外部文件的方法 补充: 回到目录 前言: 一直有 ...

  5. 慕容小匹夫 Unity3D移动平台动态读取外部文件全解析

    Unity3D移动平台动态读取外部文件全解析   c#语言规范 阅读目录 前言: 假如我想在editor里动态读取文件 移动平台的资源路径问题 移动平台读取外部文件的方法 补充: 回到目录 前言: 一 ...

  6. Unity3D移动平台动态读取外部文件全解析

    前言: 一直有个想法,就是把工作中遇到的坑通过自己的深挖,总结成一套相同问题的解决方案供各位同行拍砖探讨.眼瞅着2015年第一个工作日就要来到了,小匹夫也休息的差不多了,寻思着也该写点东西活动活动大脑 ...

  7. 细说Unity3D(一)——移动平台动态读取外部文件全解析

    前言: 一直有个想法,就是把工作中遇到的坑通过自己的深挖总结成一套相同问题的解决方案供各位同行拍砖探讨.眼瞅着2015年第一个工作日就要来到了,小匹夫也休息的差不多了,寻思着也该写点东西活动活动大脑和 ...

  8. c# .Net :Excel NPOI导入导出操作教程之读取Excel文件信息及输出

    c# .Net :Excel NPOI导入导出操作教程之读取Excel文件信息及输出 using NPOI.HSSF.UserModel;using NPOI.SS.UserModel;using S ...

  9. JNI读取assets资源文件

    源自:http://www.rosoo.net/a/201112/15459.html assets目录底下的文件会被打包到一个apk文件里,这些资源在安装时他们并没被解压,使用时是直接从apk中读取 ...

随机推荐

  1. js获取当前iframe的ID

    self.frameElement.getAttribute('id');其他属性也可以通过这种方式获取. 也可以通过 window.frameElement.id 获取当前iframe的ID

  2. js问题 项目问题

    项目问题1. js 中字符串替换函数var a = 'fajlfjal'a.replace(/b/,'a') // 不能直接改变a 而是返回替换后的值 2. vue 属性绑定中 class style ...

  3. window.open打开新窗口 参数

    1,基本描述 oNewWindow = window.open( sURL , sName , sFeatures, bReplace) window.open在打开一个窗口(其url为sURL)后, ...

  4. 逆袭之旅DAY20.xia.师父指导.数据类型

    2018-07-16  09:35:57 基础是王道 从码农--软件工程师--软件架构师 String 首字母大写,特殊引用类型,常量类 二.数组 存钱罐(只能放钱) 数据兼容 数组的长度(定义后长度 ...

  5. UVa LA 3029 City Game 状态拆分,最大子矩阵O(n2) 难度:2

    题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...

  6. 双向链表--首页大小不一卡片排序 --- react --- js

    1.4中类型(grid_type)的卡片:1:大方块:2:竖长块:3:横长块:4:小方块 var order = 0; // 创建链表 function List(head) { this.head ...

  7. OO作业总结报告3

    规格化设计的发展史 下面部分来源:https://www.cnblogs.com/eggert/p/9098446.html: 随着计算机硬件的飞速发展,以及应用复杂度越来越高,软件规模越来越大,原有 ...

  8. IDE 版本

    BDS 5 2007 D11  VER180 and VER185 RAD Studio 8 XE D15  VER 220 RAD 18 XE 10.1 Berlin D24  VER310  St ...

  9. בוא--来吧--IPA--希伯来语

    灰常好听的希伯来语歌曲, Rita唱得真好.

  10. 7.2 C++模板类实例化

    参考:http://www.weixueyuan.net/view/6399.html 总结: array < int >表明用int类型来代替模板类中的类参数“T”,编译器会将模板类ar ...