关闭

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

标签: unityunity资源加载编辑器
23497人阅读 评论(0) 收藏 举报
分类:
首先要说的是,我们的工程中有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);

	}
}



   
1
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Unity5.4 Assetbundles官方说明二(AssetBundle压缩与解压)

转载请注明出处!  上篇AssetBundle的文章:Unity5.4 Assetbundles官方说明(一),简单说明的Unity5.4中AssetBundle的打包操作,接下来将介绍AssetBu...
  • u010377179
  • u010377179
  • 2016-10-25 15:16
  • 5358

Unity教程之-Unity5.x版本AssetBundle加载研究

之前说了 “unity4.x版本AssetBundle打包研究”,没看过的请先看一下《Unity教程之-Unity3d打包Assetbundle并加载》,再来看本文,有一定的连接性。 先梳理一下思路...
  • andyhebear
  • andyhebear
  • 2016-01-08 11:44
  • 3597

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

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

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

初学Unity的过程中,会发现打包发布程序后,unity会自动将场景需要引用到的资源打包到安装包里,没有到的不会跟进去。我们在编辑器里看到的Asset中的文件结构只是工作于编辑器环境下的,在游戏中un...
  • mengdi520123
  • mengdi520123
  • 2015-03-13 10:56
  • 464

Unity3D动态加载资源的2种方式

在unity开发中,我们经常要用到动态去创建物体,这里最常见的一种就是把我们的资源做成预制物体放在Resources文件夹下,然后用Resources.Load()去动态加载出来。在Resources...
  • gaojinjingg
  • gaojinjingg
  • 2016-11-11 14:57
  • 914

Unity3D官方资源打包动态加载Demo

  • 2015-07-21 18:04
  • 553KB
  • 下载

Unity3D动态加载资源

  • 2016-07-12 14:16
  • 6.37MB
  • 下载

unity 动态加载模型等资源的文档

  • 2013-09-26 09:46
  • 67KB
  • 下载

Unity3D 网游中实现资源动态加载 。。手游消减内存必备。。。

用Unity3D制作基于web的网络游戏,不可避免的会用到一个技术-资源动态加载。比如想加载一个大场景的资源,不应该在游戏的开始让用户长时间等待全部资源的加载完毕。应该优先加载用户附近的场景资源,在游...
  • ldghd
  • ldghd
  • 2012-11-30 19:19
  • 1961

Unity3D实现动态加载游戏资源

在flash时代,资源的动态加载非常的普遍,主要是受限于网速的快慢,我们在用unity3d制作在线项目的时候,不可避免的要考虑到优化加载的问题,这篇文章算是比较好的经验之谈了,转来大家看看!用Unit...
  • amorwilliams
  • amorwilliams
  • 2014-01-13 22:00
  • 659
    个人资料
    • 访问:1006432次
    • 积分:18473
    • 等级:
    • 排名:第578名
    • 原创:189篇
    • 转载:11篇
    • 译文:6篇
    • 评论:55条