Unity5.x版本AssetBundle打包研究

Unity5的AssetBundle打包机制和以前版本不太一样。简单的说就是,只要给你要打包的资源设置一个AssetBundleName ,Unity自身会对这些设置了名字的资源进行打包,如果一个资源依赖了另一个资源。Unity自己会处理依赖关系,AssetBundleManifest文件就保存着这些资源的依赖关系。
比如一个UI面板.Prefab,依赖了一个图集Atlas,一个字体文件
做个测试:
只给UI面板3.prefab设置AssetBundleName。

打出包来看,别看只有371KB,那是因为我拿得面板不是很复杂,依赖的图集,字体,本身就不是很大。
要是项目中的话,你不处理依赖打包的话,几M都是有的。

要是有其它的UI面板,设置AssetBundleName,打出包,都是这么大的

依赖文件显示资源没依赖,这是因为每一个面板里面都单独打包了一份图集资源,字体资源。显然这是不可取的。
对于同类型的UI面板来说,这些图集和字体文件,大家用的都是同一份,只要打包出一份,大家共享就好了。
接下给图集资源,字体文件都设置AssetBundleName,再进行打包,可以看到变小了。

在看.manifest文件,有了依赖关系。

项目中,资源辣么多,总不能在编辑器里一个一个给资源进行设置AssetBundleName吧,那会蛋疼死的,是吧。
上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;
 
/// <summary>
/// 把Resource下的资源打包成.unity3d 到StreamingAssets目录下
/// </summary>
public class Builder : Editor
{
	public static string sourcePath = Application.dataPath + "/Resources";
	const string AssetBundlesOutputPath = "Assets/StreamingAssets";
 
	[MenuItem("Tools/AssetBundle/Build")]
	public static void BuildAssetBundle()
	{
		ClearAssetBundlesName ();
 
		Pack (sourcePath);
 
		string outputPath = Path.Combine (AssetBundlesOutputPath,Platform.GetPlatformFolder(EditorUserBuildSettings.activeBuildTarget));
		if (!Directory.Exists (outputPath))
		{
			Directory.CreateDirectory(outputPath);
		}
 
		//根据BuildSetting里面所激活的平台进行打包
		BuildPipeline.BuildAssetBundles (outputPath,0,EditorUserBuildSettings.activeBuildTarget);
 
		AssetDatabase.Refresh ();
 
		Debug.Log ("打包完成");
 
	}
 
	/// <summary>
	/// 清除之前设置过的AssetBundleName,避免产生不必要的资源也打包
	/// 之前说过,只要设置了AssetBundleName的,都会进行打包,不论在什么目录下
	/// </summary>
	static void ClearAssetBundlesName()
	{
		int length = AssetDatabase.GetAllAssetBundleNames ().Length;
		Debug.Log (length);
		string[] oldAssetBundleNames = new string[length];
		for (int i = 0; i < length; i++)
		{
			oldAssetBundleNames[i] = AssetDatabase.GetAllAssetBundleNames()[i];
		}
 
		for (int j = 0; j < oldAssetBundleNames.Length; j++)
		{
			AssetDatabase.RemoveAssetBundleName(oldAssetBundleNames[j],true);
		}
		length = AssetDatabase.GetAllAssetBundleNames ().Length;
		Debug.Log (length);
	}
 
	static void Pack(string source)
	{
		DirectoryInfo folder = new DirectoryInfo (source);
		FileSystemInfo[] files = folder.GetFileSystemInfos ();
		int length = files.Length;
		for (int i = 0; i < length; i++) {
			if(files[i] is DirectoryInfo)
			{
				Pack(files[i].FullName);
			}
			else
			{
				if(!files[i].Name.EndsWith(".meta"))
				{
					file (files[i].FullName);
				}
			}
		}
	}
 
	static void file(string source)
	{
		string _source = Replace (source);
		string _assetPath = "Assets" + _source.Substring (Application.dataPath.Length);
		string _assetPath2 = _source.Substring (Application.dataPath.Length + 1);
		//Debug.Log (_assetPath);
 
		//在代码中给资源设置AssetBundleName
		AssetImporter assetImporter = AssetImporter.GetAtPath (_assetPath);
		string assetName = _assetPath2.Substring (_assetPath2.IndexOf("/") + 1);
		assetName = assetName.Replace(Path.GetExtension(assetName),".unity3d");
		//Debug.Log (assetName);
		assetImporter.assetBundleName = assetName;
	}
 
	static string Replace(string s)
	{
		return s.Replace("\\","/");
	}
}
 
public class Platform
{
	public static string GetPlatformFolder(BuildTarget target)
	{
		switch (target)
		{
		case BuildTarget.Android:
			return "Android";
		case BuildTarget.iOS:
			return "IOS";
		case BuildTarget.WebPlayer:
			return "WebPlayer";
		case BuildTarget.StandaloneWindows:
		case BuildTarget.StandaloneWindows64:
			return "Windows";
		case BuildTarget.StandaloneOSXIntel:
		case BuildTarget.StandaloneOSXIntel64:
		case BuildTarget.StandaloneOSXUniversal:
			return "OSX";
		default:
			return null;
		}
	}
}

有了这个包含所有资源的依赖关系的.manifest文件,那么在加载使用一个资源的时候,就要根据这个文件,先去加载这个资源依赖的所有资源,然后再加载这个资源,然后就可以使用啦。加载这块,下次再整理。
代码都在这了,工程我就不上传了。
拜了个拜!

时间: 2024-10-11 03:50:28

Unity5.x版本AssetBundle打包研究的相关文章

Unity5.x版本AssetBundle加载研究

之前说了 “Unity5.x版本AssetBundle打包研究”,没看过的请先看一下:http://www.shihuanjue.com/?p=57再来看本文,有一定的连接性. 先梳理一下思路:要加载一个资源A,必须先去加载它的所有依赖资源要知道这个资源A依赖了哪些资源,必须先去加载AssetBundleManifest通过AssetBundleManifest对象的GetAllDependencies(A)方法,获取它依赖的所有资源.依赖资源都加载了,就可以去真正加载资源A了. 注意点:1.资

Unity3d 5.x AssetBundle打包与加载

1.AssetBundle打包 unity 5.x版本AssetBundle打包,只需要设置好AssetBundle的名称后,unity会自动将其打包,无需处理其他,唯独需要做的是设置好个AssetBundle的名称. 注意:AssetBunlde的名称只能设置小写字母,即使你写成大写也会被自动转置成大写字母,而且名称中支持"/",如:"AssetBundles/cube.unity3d",.unity3d的后缀是自己设置的,可以不设置 代码: using Unit

AssetBundle打包优化解决方式

第一阶段:AssetBundle出一套解决方式 1.解决如今同一个资源打2个bundle的冗余问题 2.測试验证节省资源的比率是多少 问题拆分 一.bundle反复 问  题  :同样资源拆分问题? 解决方式:1.制作场景时将同样部分分开 制作方法:将每一个场景同样部分放到同一个文件夹,不同部分保留在场景中 打包方法:a.打成独立的bundle,不同部分放到每一个场景中打成bundle b.用xml记录下每一个场景中公共部分的transform,bundle名称.资源名称.父节点信息 优    

AssetBundle打包优化解决方案

第一阶段:AssetBundle出一套解决方案 1.解决现在同一个资源打2个bundle的冗余问题 2.测试验证节省资源的比率是多少 问题拆分 一.bundle重复 问  题  :相同资源拆分问题? 解决方案:1.制作场景时将相同部分分开 制作方法:将每个场景相同部分放到同一个目录,不同部分保留在场景中 打包方法:a.打成独立的bundle,不同部分放到每个场景中打成bundle b.用xml记录下每个场景中公共部分的transform,bundle名称.资源名称.父节点信息 优    点:打包

Unity5新的AssetBundle系统使用心得

Unity的AssetBundle系统是对资源管理的一个扩展,动态更新,网页游戏,资源下载都是基于AssetBundle系统的.但是不得不说,这个系统非常恶心,坑很深.至于有多深,请看这篇文章: http://www.cnblogs.com/ybgame/p/3973177.html 原先的AssetBundle系统需要自己写一大坨导出的代码(BuildPipeline),这个新手会无从下手,老手也经常会被坑到.想正确处理好资源的依赖关系从而保证资源完整而又不会产生重复资源,确实不是一件非常容易

Unity AssetBundle打包与资源更新

Unity的AssetBundle打包是一件让人头疼的事情,当我接手这项工作时,我以为最多只用两个周就可以把整个打包和资源热更新的流程搞定,结果还是花了一个月,期间踩坑无数,总结出来希望能够节约别人的时间. (一)你的游戏项目是什么类型的? 在开始写打包的Editor脚本之前,你最好先详细考察一下你们的游戏项目是什么类型?是端游,手游还是页游?因为这三者涉及到bundle包的资源管理策略截然不同,如果你们是跨平台发布,那我建议你最好用宏来切换管理策略. 我先分享一下我曾经接手过打包工作的两个项目

一个灵活的AssetBundle打包工具

尼尔:机械纪元 上周介绍了Unity项目中的资源配置,今天和大家分享一个AssetBundle打包工具.相信从事Unity开发或多或少都了解过AssetBundle,但简单的接口以及众多的细碎问题也给工作带来较多的困扰.今天分享AssetBundle工具的实践与想法,相信这块内容对帮助理解AssetBundle有较大的帮助. Unity提供了两种资源加载方式,一种是Resources,另外种就是AssetBundle.所有的资源只要放在Resources目录下,在打包的时候会自动打进去,并可以通

Assetbundle 打包加载及服务器加载等(采用unity3d5.0后的新版)

Assetbundle为资源包不是资源 打包1:通过脚本指定打包 AssetBundleBuild ab = new AssetBundleBuild { assetBundleName = PlayerSettings.bundleVersion + "@" + "zhao",//资源包assets的名字 assetNames = new string[1],  //包里的每个资源的名字 }; string outputPath = Path.Combine(Ut

[cb] Assetbundle打包(一)

Unity的Assetbundle是Unity Pro提供的功能. 理解:Asset 资源,资产:Bundle :包,一批,捆:字面上的意思,就是把资源打包. 在项目中的实际应用:Art工程,Prefab打包成AssetBundle到Produect目录,Client工程读取AssetBundle; 下面这张图是Art工程 放在Product目录下的Prefab都会打包成AssetBundle 打包AssetBundle到Product目录下[Assetbundle有运行平台之分] Client