Unity3D中AssetBundle应用
工程中的模型等资源转化为Prefab后,打包成AssetBundle,可以大幅降低资源的空间占有度,并且提高资源加载的效率。
一、AssetBundle的打包
先看下打包Prefab的脚本代码,这段脚本可以将一个或多个选中的Prefab打包成对应名称的.assetbundle文件:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class CreateAssetBundlesMainClass : MonoBehaviour {
[MenuItem("Custom Editor/Create AssetBunldes Main")]
static void CreateAssetBundlesMain()
{
//获取在Project视图中选择的所有游戏对象
Object[] SelectedAsset = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets); //遍历所有的游戏对象
foreach (Object obj in SelectedAsset)
{
string sourcePath = AssetDatabase.GetAssetPath(obj);
//本地测试:建议最后将Assetbundle放在StreamingAssets文件夹下,如果没有就创建一个,因为移动平台下只能读取这个路径
//StreamingAssets是只读路径,不能写入
//服务器下载:就不需要放在这里,服务器上客户端用www类进行下载。
string targetPath = Application.dataPath + "/StreamingAssets/" + obj.name + ".assetbundle";
if (BuildPipeline.BuildAssetBundle(obj, null, targetPath,
BuildAssetBundleOptions.CollectDependencies, BuildTarget.StandaloneWindows64))
{
Debug.Log(obj.name + "资源打包成功");
}
else
{
Debug.Log(obj.name + "资源打包失败");
}
}
//刷新编辑器
AssetDatabase.Refresh(); }
}
以上脚本不用挂在到场景中的游戏对象,只需要保存在Project中就可以。在菜单栏会生成一系列选项(All是打包所有Prefab、Main是打包选定的Prefab、Scene是打包场景;上述代码是打包单个Prefab):

在Project中选中要打包的Prefab,一个或多个,点击Create AssetBundles Main,就可以打包出对应的AB。比如选中了Prefab0和Prefab1再点击Create AssetBundles Main,就会生成出Prefab0.assetbundle和Prefab1.assetbundle,打包出的文件会保存在StreamingAssetes文件夹中:

打包所有Prefab的代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor; public class CreateAssetBundlesALLClass : MonoBehaviour { [MenuItem("Custom Editor/Create AssetBunldes ALL")]
static void CreateAssetBundlesALL()
{ Caching.ClearCache(); string Path = Application.dataPath + "/StreamingAssets/ALL.assetbundle"; Object[] SelectedAsset = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets); foreach (Object obj in SelectedAsset)
{
Debug.Log("Create AssetBunldes name :" + obj);
} //这里注意第二个参数就行
if (BuildPipeline.BuildAssetBundle(null, SelectedAsset, Path,
BuildAssetBundleOptions.CollectDependencies, BuildTarget.StandaloneWindows64))
{
AssetDatabase.Refresh();
}
else
{ }
}
}
选中Prefab0和Prefab1再点击Create AssetBundles All,就会将Prefab0和Prefab1合在一起打包为一个文件——ALL.assetbundle。
二、AssetBundle的加载
下面是加载AB的脚本,这个文件需要挂在到场景中的游戏对象上才能有效。
using UnityEngine;
using System.Collections; public class RunScript : MonoBehaviour
{
public static string PathURL; private void OnEnable()
{
PathURL = "file://" + Application.dataPath + "/StreamingAssets/";
} void OnGUI()
{
if (GUILayout.Button("Load One Assetbundle"))
{
StartCoroutine(LoadMainGameObject(PathURL + "Prefab0.assetbundle"));
//StartCoroutine(LoadMainGameObject(PathURL + "Prefab1.assetbundle"));
} if (GUILayout.Button("Load All Assetbundle"))
{
StartCoroutine(LoadALLGameObject(PathURL + "ALL.assetbundle"));
} } //读取一个资源 private IEnumerator LoadMainGameObject(string path)
{
WWW bundle = new WWW(path); yield return bundle; //加载到游戏中
yield return Instantiate(bundle.assetBundle.mainAsset); bundle.assetBundle.Unload(false);
//AssetBundle.Unload(false):释放AssetBundle文件内存镜像
//AssetBundle.Unload(true):释放AssetBundle文件内存镜像同时销毁所有已经Load的Assets内存对象 } //读取全部资源 private IEnumerator LoadALLGameObject(string path)
{
WWW bundle = new WWW(path); yield return bundle; //通过Prefab的名称把他们都读取出来
Object obj0 = bundle.assetBundle.LoadAsset("Prefab0");
Object obj1 = bundle.assetBundle.LoadAsset("Prefab1"); //加载到游戏中
yield return Instantiate(obj0);
yield return Instantiate(obj1);
bundle.assetBundle.Unload(false);
} }
游戏运行后脚本使游戏左上角生成两个加载按钮,点击后会从之前保存AB的路径将其加载进来,如点击Load ALL Assetbundle,就会加载ALL.assetbundle,从而把两个Prefab都加载进来:

加载脚本中使用了协程,主要原因是为了将AB的下载和Prefab的加载分离到两个逻辑帧中进行,避免下载和读取的冲突。使用yield return,可以起到检查当前返回的异步对象是否能够顺利进入到下一帧的作用。

附一张AB的生命周期图:

Unity3D中AssetBundle应用的更多相关文章
- Unity3D 中材质球(Material)预制体打包成AB(AssetBundle)出现材质丢失问题的解决方案
关于Unity3D中打AB(AssetBundle)资源包,默认是不连Shader一同打包进去的,所以得自行添加,添加方式比较简单,不需要往项目中添加Shader,只是点选一下就可以了,具体实现方式如 ...
- Unity3d中使用assetbundle
1.导出assetbundle: ①单个资源导出成assetbundle: ②多个资源导出成一个assetbundle: 2.读取assetbundle: ①加载到内存: ②解压为具体资源. 1.导出 ...
- Unity3D之Assetbundle
原地址: Unity3D之Assetbundle 有几个地方需要注意下 1.如何解决资源重复加载的问题 2.初始化了就直接出现在场景中了 感觉怪怪的 3.标红的地方要注意下 prefab上挂载的脚 ...
- 在Unity3d中解析Lua脚本的方法
由于近期项目中提出了热更新的需求,因此本周末在Lua的陪伴下度过.对Lua与Unity3d的搭配使用,仅仅达到了一个初窥门径的程度,记录一二于此.水平有限,欢迎批评指正. 网络上关于Lua脚本和Uni ...
- Unity3D中的线程与协程
线程 Unity3D是以生命周期主线程循环进行游戏开发. Unity3D中的子线程无法运行Unity SDK(开发者工具包,软件包.软件框架)跟API(应用程序编程接口,函数库). 限制原因:大多数游 ...
- 【Unity3d游戏开发】Unity3D中的3D数学基础---向量
向量是2D.3D数学研究的标准工具,在3D游戏中向量是基础.因此掌握好向量的一些基本概念以及属性和常用运算方法就显得尤为重要.在本篇博客中,马三就来和大家一起回顾和学习一下Unity3D中那些常用的3 ...
- Unity3D中可中途释放的单例
Unity3D中可中途释放的单例 使用静态类,静态变量的坏处是从程序加载后就一直占用内存,想要释放比较麻烦,可是之前使用的单例,没有提供释放的方法,那是不是也同静态的一样直到程序结束菜释放?那单例的好 ...
- 图文详解Unity3D中Material的Tiling和Offset是怎么回事
图文详解Unity3D中Material的Tiling和Offset是怎么回事 Tiling和Offset概述 Tiling表示UV坐标的缩放倍数,Offset表示UV坐标的起始位置. 这样说当然是隔 ...
- unity3d中 刚体(Rigidbody) 碰撞体(Collider) 触发器(Is Trigger)
刚体(Rigidbody)的官方(摘自Unity3d的官方指导书<Unity4.x从入门到精通>)解释如下: Rigidbody(刚体)组件可使游戏对象在物理系统的控制下来运动,刚体可 ...
随机推荐
- 小A与小B-(双向bfs)
链接:https://ac.nowcoder.com/acm/contest/549/G来源:牛客网 题目描述 小A与小B这次两个人都被困在了迷宫里面的两个不同的位置,而他们希望能够迅速找到对方,然后 ...
- mapreduce 内存分配
稍微有点mapreduce使用经验的同学肯定对OOM不陌生,对的,我目前在mapReduce里面遇到的最多的报错也是内存分配出错,所以看到好多hadoop执行脚本里面有好多关于内存的参数,虽然是知道和 ...
- dubbo常见面试问题(二)
1.什么是Dubbo? Duubbo是一个RPC远程调用框架, 分布式服务治理框架 2.什么是Dubbo服务治理? 服务与服务之间会有很多个Url.依赖关系.负载均衡.容错.自动注册服务 3.Dubb ...
- Java框架spring Boot学习笔记(五):Spring Boot操作MySQL数据库增、删、改、查
在pom.xml添加一下代码,添加操作MySQL的依赖jar包. <dependency> <groupId>org.springframework.boot</grou ...
- dubbo 面试
1.使用dubbo+zookeeper ,如果注册中心挂掉,是否可以继续通信?(zk集群可以达到高可用,但是如果全部挂掉呢?) 我答了不可以吧(项目没用过,自学没又这深度) 正确答案: dubbo使用 ...
- Ubuntu 16.04 安装Kinect V2驱动
1.下载源代码 git clone https://github.com/OpenKinect/libfreenect2.git 2.依赖项安装 sudo apt-get install build- ...
- HDU2034
#include <bits/stdc++.h> using namespace std; int main() { int n,m,val; set<int>::iterat ...
- Json列表数据查找更新
/* 从Json数组按某个字段中查找记录 IN array 数据列表 fieldName 字段名称 fieldValue 字段值 OUT 查找到的数据列表 */ var SearchRecordsFr ...
- c语言知识
1. 指针 https://blog.csdn.net/lwbeyond/article/details/6180640 http://www.cnblogs.com/lvyahui/p/696528 ...
- 将IP转换为16进制,用于IPv4-IPv6
# --*-- coding: utf-8 --*--# create by xiaocaiji while 1: str_ip = input("input a IP:") li ...