原文地址:http://www.unity.5helpyou.com/2954.html
本篇Unity3d教程我们继续学习下如何制作利用AssetBundle来打包制作我们的数据文件,并在游戏中读取AssetBundle数据文件
由于我们要将模型资源放在远程的服务器端,但如果直接放fbx模型是不可以加载的,所以我们可以将fbx做成预设或者是直接将其打包成assetbundle格式的,然后通过www来加载获取。
说下使用方法:
1、把附件脚本放到工程文件夹下的…\Assets\Editor文件夹下。
2、在工程的Project视图里点击想要保存的资源,网络上推荐的是Prefab,右键点击,选择菜单里最下面的两个选项任意一个都可以,第一个选项对应的自定义属性有一个过期了,但是不影响使用。
3、指定文件的构建路径和文件后缀,后缀无所谓。
4、推荐制造做法:
任何形式的资源都可以,包括集合资源,比如创建一个空的GameObject,把所有想要关联的其他GameObject都拖进去,然后在project视图里创建一个prefab,将这个集合资源GameObject拖进去作为一个prefab。执行上面的第2、3步骤。
官方的讲解:http://game.ceeger.com/Script/BuildPipeline/BuildPipeline.BuildAssetBundle.html
1.首先要讲一下不同平台下的一个StreamingAssets路径,这是不同的。
1
2
3
4
5
6
7
8
9
10
11
|
//不同平台下StreamingAssets的路径是不同的,这里需要注意一下。
public
static
readonly
string
PathURL =
#if UNITY_ANDROID //安卓
"jar:file://"
+ Application.dataPath +
"!/assets/"
;
#elif UNITY_IPHONE //iPhone
Application.dataPath +
"/Raw/"
;
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR //windows平台和web平台
"file://"
+ Application.dataPath +
"/StreamingAssets/"
;
#else
string
.Empty;
#endif
|
这就获取到了不同平台的一个路径,我们可以将打包的文件放在这些路径下,然后再从这路径去读取资源。
2.关于打包assetbundle的脚本
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
|
using
UnityEngine;
using
System.Collections;
using
UnityEditor;
public
class
Test : Editor
{
//打包单个
[MenuItem(
"Custom Editor/Create AssetBunldes Main"
)]
static
void
CreateAssetBunldesMain ()
{
//获取在Project视图中选择的所有游戏对象
Object[] SelectedAsset = Selection.GetFiltered (
typeof
(Object), SelectionMode.DeepAssets);
//遍历所有的游戏对象
foreach
(Object obj
in
SelectedAsset)
{
//本地测试:建议最后将Assetbundle放在StreamingAssets文件夹下,如果没有就创建一个,因为移动平台下只能读取这个路径
//StreamingAssets是只读路径,不能写入
//服务器下载:就不需要放在这里,服务器上客户端用www类进行下载。
string
targetPath = Application.dataPath +
"/StreamingAssets/"
+ obj.name +
".assetbundle"
;
if
(BuildPipeline.BuildAssetBundle (obj,
null
, targetPath, BuildAssetBundleOptions.CollectDependencies)) {
Debug.Log(obj.name +
"资源打包成功"
);
}
else
{
Debug.Log(obj.name +
"资源打包失败"
);
}
}
//刷新编辑器
AssetDatabase.Refresh ();
}
[MenuItem(
"Custom Editor/Create AssetBunldes ALL"
)]
static
void
CreateAssetBunldesALL ()
{
Caching.CleanCache ();
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)) {
AssetDatabase.Refresh ();
}
else
{
}
}
[MenuItem(
"Custom Editor/Create Scene"
)]
static
void
CreateSceneALL ()
{
//清空一下缓存
Caching.CleanCache();
string
Path = Application.dataPath +
"/MyScene.unity3d"
;
string
[]levels = {
"Assets/Level.unity"
};
//打包场景
BuildPipeline.BuildPlayer( levels, Path,BuildTarget.WebPlayer, BuildOptions.BuildAdditionalStreamedScenes);
AssetDatabase.Refresh ();
}
}
|
前提要新手动创建一个StreamingAssets文件夹
3.读取资源,这里只举例从本地读取,跟从网络读取是一样的,可以参考官方文档:
http://game.ceeger.com/Script/WWW/WWW.html
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
|
using
UnityEngine;
using
System.Collections;
public
class
RunScript : MonoBehaviour
{
//不同平台下StreamingAssets的路径是不同的,这里需要注意一下。
public
static
readonly
string
PathURL =
#if UNITY_ANDROID
"jar:file://"
+ Application.dataPath +
"!/assets/"
;
#elif UNITY_IPHONE
Application.dataPath +
"/Raw/"
;
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR
"file://"
+ Application.dataPath +
"/StreamingAssets/"
;
#else
string
.Empty;
#endif
void
OnGUI()
{
if
(GUILayout.Button(
"Main Assetbundle"
))
{
//StartCoroutine(LoadMainGameObject(PathURL + "Prefab0.assetbundle"));
//StartCoroutine(LoadMainGameObject(PathURL + "Prefab1.assetbundle"));
StartCoroutine(LoadMainCacheGameObject(PathURL +
"Prefab0.assetbundle"
));
StartCoroutine(LoadMainCacheGameObject(PathURL +
"Prefab1.assetbundle"
));
}
if
(GUILayout.Button(
"ALL Assetbundle"
))
{
StartCoroutine(LoadALLGameObject(PathURL +
"ALL.assetbundle"
));
}
if
(GUILayout.Button(
"Open Scene"
))
{
StartCoroutine(LoadScene());
}
}
//读取一个资源
private
IEnumerator LoadMainGameObject(
string
path)
{
WWW bundle =
new
WWW(path);
yield
return
bundle;
//加载到游戏中
yield
return
Instantiate(bundle.assetBundle.mainAsset);
bundle.assetBundle.Unload(
false
);
}
//读取全部资源
private
IEnumerator LoadALLGameObject(
string
path)
{
WWW bundle =
new
WWW(path);
yield
return
bundle;
//通过Prefab的名称把他们都读取出来
Object obj0 = bundle.assetBundle.Load(
"Prefab0"
);
Object obj1 = bundle.assetBundle.Load(
"Prefab1"
);
//加载到游戏中
yield
return
Instantiate(obj0);
yield
return
Instantiate(obj1);
bundle.assetBundle.Unload(
false
);
}
private
IEnumerator LoadMainCacheGameObject(
string
path)
{
WWW bundle = WWW.LoadFromCacheOrDownload(path,5);
yield
return
bundle;
//加载到游戏中
yield
return
Instantiate(bundle.assetBundle.mainAsset);
bundle.assetBundle.Unload(
false
);
}
private
IEnumerator LoadScene()
{
WWW download = WWW.LoadFromCacheOrDownload (
"file://"
+Application.dataPath +
"/MyScene.unity3d"
, 1);
yield
return
download;
var bundle = download.assetBundle;
Application.LoadLevel (
"Level"
);
}
}
|
如果assetbundle文件放在服务器端,直接用www.loadfromcacheordownload()通过版本来控制是否从服务器下载并保存到本地。本人亲自测试,这个方法是能下载到本地的,至于下载在本地哪儿我就不太清楚了,我猜测应该是存在沙盒文件下(移动开发者的朋友应该知道),当然也可以自己来做版本控制,那样更灵活,并且摆脱www.loadfromcacheordownload()方法的束缚,貌似这个方法存贮文件是有空间大小限制的,据说是50M,本人没有亲自考证,后期我会自己做一个版本控制!
好了,本篇unity3d教程到此结束,下篇我们学习如何利用FileStream来读取我们的AssetBundle数据并加载文件!