【Unity】Unity中资源动态加载的两种方式之AssetsBundle

原创 2015年07月07日 11:57:06
首先要说的是,我们的工程中有2个脚本,分别是:
Build(编辑器类脚本,无需挂载到任何物体),但是必须要把Build脚本放到Editor文件夹中
Load脚本,挂载到摄像机上<pre name="code" class="csharp">using UnityEngine;
using System.Collections;
using UnityEditor;

public class Build : MonoBehaviour
{
	// 编辑器类
	[MenuItem("Build/BuildAsset")]
	// 打包单个资源的方法
	static void BuildAsset ()
	{
		// 将物体打包到/AssetsBundles路径下同时命名为Cube1.assetbundle
		string targetPath = Application.dataPath + "/AssetsBundles/Cube1.assetbundle"; 
		// BuildPipeline 打包用 Selection (Selection.activeObject 在编辑器中选中的对象)
		// 第二个参数null,是打包多个资源的时候用的,多个资源就是数组,单个资源的时候这个参数不用写
		// 第三个参数是路径,你想把这个资源放到什么位置就写什么,并且还要命名为.assetbundl格式
		BuildPipeline.BuildAssetBundle (Selection.activeObject, null, targetPath);
		// 刷新资源,直接可以在unity中看到刚才打包的东西
		AssetDatabase.Refresh();
	}

	// --------------------------------------------------------------------------------


	[MenuItem("Build/BuildMultiAsset")]
	// 打包多个资源的时候使用这个方法
	static void BuildMultiAsset()
	{
		// 将物体打包到/AssetsBundles路径下同时命名为Cubes.assetbundle
		string target = Application.dataPath + "/AssetsBundles/Cubes.assetbundle";
		// 因为打包多个游戏对象,所以是一个数组,typr(Object)表示,只要选择的物体是Object类型就可以
		// 并且选择的模式是深度资源搜索(具体学名到底叫啥我也忘了。。。),
		// 意思是只要你选择的object对象下面如果还有关联的东西就都会一起打包(unity导出场景的时候应该可以感受到)
		Object[] cubes = Selection.GetFiltered(typeof(Object),SelectionMode.DeepAssets);
		// 打包开始,因为是一堆资源,所以主资源为null,剩下两个参数意思同上
		BuildPipeline.BuildAssetBundle(null,cubes,target);
		// 刷新资源,直接可以在unity中看到刚才打包的东西
		AssetDatabase.Refresh();
	}

	// --------------------------------------------------------------------------------

	[MenuItem("Build/BuildScene")]
	// 打包场景的方法
	static void BuildScene()
	{
		// 场景名字,为什么是数组呢(因为参数里要求这个参数是数组类型。。。。)
		string [] sceneName =  new string[]{Application.dataPath + "/scene1.unity"};
		// 将物体打包到/AssetsBundles路径下同时命名为Scene1.assetbundle
		string targetPath = Application.dataPath + "/AssetsBundles/Scene1.assetbundle";
		// 注意打包的方法名已经变成流类型了,后面的最后一个参数表示你要在上面平台运行
		// iphone平台就是用BuildTarget.iPhone这个参数
		// 安卓平台就是用BuildTarget.Android这个参数
		// 类似参数可以自己查看。。。
		BuildPipeline.BuildStreamedSceneAssetBundle(sceneName,targetPath,BuildTarget.WebPlayer);
		// 刷新资源,直接可以在unity中看到刚才打包的东西
		AssetDatabase.Refresh();
	}
	// --------------------------------------------------------------------------------
	[MenuItem("Build/BuildDependence")]
	static void BuildDependence()
	{
		// 对一些公共参数的定义 //
		// 定义路径文件夹是Application.dataPath读取后的路径 加上 "/AssetBundles"
		string path = Application.dataPath + "/AssetsBundles";
		// 定义资源包的依赖关系选项
		BuildAssetBundleOptions buildOp = BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets;

		// ---------------------------------------------------------------------

		// Push和Pop是成对出现的,他们的作用是维持一个依赖关系
		// 我们当前的资源包关系是这样的:
		/*
			Tex1.assetbundle资源包(Tex1的包里有以下2个资源包)
				c1.assetbundle资源包(c1和c2是平级关系)
				c2.assetbundle资源包	
		*/
		//依赖资源压栈
		BuildPipeline.PushAssetDependencies();

		// 替代之前的selection的手动选择方式
		Object tex = AssetDatabase.LoadMainAssetAtPath("Assets/Resources/Tex1.jpg");

		// 所有后续资源将共享这一资源包中的内容,但是你要保证的是,在使用c1和c2这种内层依赖包时
		// 你已经加载了最外层资源包Tex1
		BuildPipeline.BuildAssetBundle(tex, null,path + "/Tex1.assetbundle", buildOp);

		// 这里使用一对Push和Pop是将我们接下来加载的c1资源包和tex依赖起来
		BuildPipeline.PushAssetDependencies();
		Object c1 = AssetDatabase.LoadMainAssetAtPath("Assets/Resources/Cube1.prefab");
		BuildPipeline.BuildAssetBundle(c1, null, path + "/c1.assetbundle", buildOp);
		BuildPipeline.PopAssetDependencies();

		// 同上
		BuildPipeline.PushAssetDependencies();
		Object c2 = AssetDatabase.LoadMainAssetAtPath("Assets/Resources/Cube2.prefab");
		BuildPipeline.BuildAssetBundle(c2, null,path + "/c2.assetbundle", buildOp);
		BuildPipeline.PopAssetDependencies();

		// 依赖资源出栈
		BuildPipeline.PopAssetDependencies();
		AssetDatabase.Refresh();
	}


}

using UnityEngine;
using System.Collections;

public class Load : MonoBehaviour {
	// 所有公共的路径名开头都是这个文件夹,所以单列出来,简化后面代码
	public static string loadPath  = "file://" + Application.dataPath +"/AssetsBundles";

	// 画一个按钮
	void OnGUI()
	{
		if(GUILayout.Button("LoadTex"))
		{
			StartCoroutine(LoadTex(loadPath));
		}
		if (GUILayout.Button("LoadCube")) {
			// 因为下面的方法都是协同程序,所以需要手动开启协同程序
			StartCoroutine(LoadCube(loadPath));
		}
		if (GUILayout.Button("LoadVersion")) {
			StartCoroutine(LoadVersion(loadPath));
		}
		if (GUILayout.Button("LoadCubes")) {
			StartCoroutine(LoadCubes(loadPath));
		}
		if (GUILayout.Button("LoadScene")) {
			StartCoroutine(LoadScene(loadPath));
		}
	}

	// 协同方法,加载1个cube的方法
	IEnumerator LoadCube (string path)
	{
		// 下载一个已经打包好的assetbundle(打包需要在Build脚本中实现,在工程里手动打包)
		WWW www = new WWW(path + "/Cube1.assetbundle");
		// 返回下载的assetbundle包
		yield return www;
		// 实例化一个cube,游戏物体使用assetbundle中的主资源(因为是单独打包,所以只有一个主资源),后面是实例化物体的位置和角度信息
		Instantiate(www.assetBundle.mainAsset,new Vector3(Random.Range(0,9),Random.Range(0,9),Random.Range(0,9)),Quaternion.identity);
		// 实例化成功后输出资源名字
		print(www.assetBundle.mainAsset);
		// 卸载刚才已经下载的资源在内存中(就是在内存中删除)
		www.assetBundle.Unload(false);
	}


	// 协同方法,加载多个cube的方法
	IEnumerator LoadCubes(string path)
	{
		// 下载一个已经打包好的包含多个游戏对象的资源包
		WWW www = new WWW(path + "/Cubes.assetbundle");
		yield return www;
		// 下载资源包中的其中一个名字叫Cube1的物体(这个名字一定是在刚才下载的那个包里有的)
		Instantiate(www.assetBundle.Load("Cube1"),Vector3.up,Quaternion.identity);
		// 下载资源包中的其中一个名字叫Cube2的物体(这个名字一定是在刚才下载的那个包里有的)
		Instantiate(www.assetBundle.Load("Cube2"),Vector3.up,Quaternion.identity);
	}

	// 协同方法,加载一个场景的方法
	IEnumerator LoadScene(string path)
	{
		// 下载已经打包好的场景
		WWW www = new WWW(path + "/scene1.assetbundle");
		yield return www;
		// 获取到包含场景的assetbundle资源包
		AssetBundle bundle = www.assetBundle;
		// 加载的是资源包中的scene1场景,如果没有上面的这行代码,就无法加载这个场景
		Application.LoadLevel("scene1");
	}




	IEnumerator LoadVersion(string path)
	{	
		// 根据版本号加载assetbundle
		WWW www = WWW.LoadFromCacheOrDownload(path + "/Cube1.assetbundle",1);
		yield return www;
		if (www.error != null) {
			print(www.error);
		} else {
			Instantiate(www.assetBundle.mainAsset);
		}
	}


	IEnumerator LoadTex(string path)
	{
		WWW www = new WWW(path + "/Tex1.assetbundle");
		WWW wwwc1 = new WWW(path + "/c1.assetbundle");
		yield return www;
		print(www.assetBundle.mainAsset);
		Instantiate(wwwc1.assetBundle.mainAsset);

	}
}



                    
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Unity中资源动态加载的几种方式比较

初学Unity的过程中,会发现打包发布程序后,unity会自动将场景需要引用到的资源打包到安装包里,没有到的不会跟进去。我们在编辑器里看到的Asset中的文件结构只是工作于编辑器环境下的,在游戏中un...
  • leonwei
  • leonwei
  • 2014年01月17日 16:15
  • 61592

unity3d C#相关小知识点集合

1、AssetDatabase.LoadMainAssetAtPath函数: 返回一个载入的资源对象。 参数assetPath:是以项目Assets文件夹为根目录的相对路径。 2、Debug.Lo...

Unity3D技术之资源数据库 (AssetDatabase)详解

欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,我们致力于打造业内unity3d培训、学习第一品牌...

Unity资源热更之AssetBundle(1)———基本介绍

聊到热更就必须先了解AssetBundle. 1.AssetBundle是什么呢?AssetBundles 是有 Unity 编辑器在编辑环境中(enit-time)创建的一些列的文件,这些文件可以...

Unity手游之路<十一>资源打包Assetbundle

在手游的运营过程中,更新资源是比不可少的。资源管理第一步是资源打包。传统的打包可以将所有物件制成预设Prefab,打包成场景。今天我们来一起学习官方推荐的Assetbundle,它是Unity(Pro...
  • janeky
  • janeky
  • 2013年12月30日 00:22
  • 96356

SelectionMode 选择模式

SelectionMode 选择模式,打包资源
  • nmg10
  • nmg10
  • 2016年09月21日 09:51
  • 772

Unity3d之AssetBundle打包与读取

一、创建Assetbundle 在unity3d开发的游戏中,无论模型,音频,还是图片等,我们都做成Prefab,然后打包成Assetbundle,方便我们后面的使用,来达到资源的更新。       ...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Unity中资源打包成Assetsbundle的资料整理

最近在研究Unity中关于资源打包的东西,网上看了一堆资料,这里做个整合,说整合,其实也就是Ctrl-C + Ctrl-V,不是原创 首先为了尊重原创,先贴出原创者的文章地址: http://blog...

Unity资源处理机制(Assets/WWW/AssetBundle/...)读取和加载资源方式详解

Unity资源机制 1、概述       本文意在阐述Unity资源机制相关的信息,以及一些关于个人的理解与试验结果。另外还会提及一些因机制问题可能会出现的异常以及处理建议。大部分机制信息来源于官...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【Unity】Unity中资源动态加载的两种方式之AssetsBundle
举报原因:
原因补充:

(最多只允许输入30个字)