好久没弄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
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;
public class DoAssetbundle : MonoBehaviour {
/// <summary>
/// 查看所有的Assetbundle名称(设置Assetbundle Name的对象)
/// </summary>
[MenuItem("AssetBundle/Get AssetBundle names")]
static void GetNames()
{
var names = AssetDatabase.GetAllAssetBundleNames(); //获取所有设置的AssetBundle
foreach (var name in names)
Debug.Log("AssetBundle: " + name);
}
/// <summary>
/// 自动打包所有资源(设置了Assetbundle Name的资源)
/// </summary>
[MenuItem("AssetBundle/Create PC AssetBundles")] //设置编辑器菜单选项
static void CreateAllAssetBundles()
{
//打包资源的路径,打包在对应平台的文件夹下
string targetPath = Application.dataPath + "/StreamingAssets/PCAssetsResources/";
if(!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
//打包资源
BuildPipeline.BuildAssetBundles(targetPath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);
//刷新编辑器
AssetDatabase.Refresh();
}
[MenuItem("AssetBundle/Create Android AssetBundles")] //设置编辑器菜单选项
static void CreateAndroidAssetBundles()
{
//打包资源的路径,打包在对应平台的文件夹下
string targetPath = Application.dataPath + "/StreamingAssets/AndroidAssetsResources/";
if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
//打包资源
BuildPipeline.BuildAssetBundles(targetPath, BuildAssetBundleOptions.None, BuildTarget.Android);
//刷新编辑器
AssetDatabase.Refresh();
}
[MenuItem("AssetBundle/Create IOS AssetBundles")] //设置编辑器菜单选项
static void CreateIOSAssetBundles()
{
//打包资源的路径,打包在对应平台的文件夹下
string targetPath = Application.dataPath + "/StreamingAssets/IOSAssetsResources/";
if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
//打包资源
BuildPipeline.BuildAssetBundles(targetPath, BuildAssetBundleOptions.None, BuildTarget.iOS);
//刷新编辑器
AssetDatabase.Refresh();
}
/// <summary>
/// 将某一文件夹中的资源进行分离打包,即把依赖资源分离出来打包
/// </summary>
[MenuItem("AssetBundle/Set Main AssetbundleName")]
public static void SetMainAssetBundleName()
{
string fullPath = Application.dataPath + "/AssetBundle/MainAssets/"; //将Assets/Prefab/文件夹下的所有预设进行打包
SetAssetBundleName(fullPath, true);
}
/// <summary>
/// 将某一文件夹中的资源进行整体打包,即不分离依赖资源,全部打成一个资源包
/// </summary>
[MenuItem("AssetBundle/Set Total Assetbundle Name")]
public static void SetTotalAssetBundleName()
{
string fullPath = Application.dataPath + "/AssetBundle/TotalAssets/"; //将Assets/Prefab/文件夹下的所有预设进行打包
SetAssetBundleName(fullPath, false);
}
/// <summary>
/// 设置资源的资源包名称
/// </summary>
/// <param name="path">资源主路径</param>
/// <param name="ContainDependences">资源包中是否包含依赖资源的标志位:true表示分离打包,false表示整体打包</param>
static void SetAssetBundleName(string path, bool ContainDependences = false)
{
//ClearAssetBundlesName(); //先清楚之前设置过的AssetBundleName,避免产生不必要的资源也打包
if (Directory.Exists(path))
{
EditorUtility.DisplayProgressBar("设置AssetName名称", "正在设置AssetName名称中...", 0f); //显示进程加载条
DirectoryInfo dir = new DirectoryInfo(path); //获取目录信息
FileInfo[] files = dir.GetFiles("*", SearchOption.AllDirectories); //获取所有的文件信息
for (var i = 0; i < files.Length; ++i)
{
FileInfo fileInfo = files[i];
EditorUtility.DisplayProgressBar("设置AssetName名称", "正在设置AssetName名称中...", 1f * i / files.Length);
if (!fileInfo.Name.EndsWith(".meta")) //判断去除掉扩展名为“.meta”的文件
{
string basePath = "Assets" + fileInfo.FullName.Substring(Application.dataPath.Length); //编辑器下路径Assets/..
string assetName = fileInfo.FullName.Substring(path.Length); //预设的Assetbundle名字,带上一级目录名称
assetName = assetName.Substring(0, assetName.LastIndexOf('.')); //名称要去除扩展名
assetName = assetName.Replace('\', '/'); //注意此处的斜线一定要改成反斜线,否则不能设置名称
AssetImporter importer = AssetImporter.GetAtPath(basePath);
if (importer && importer.assetBundleName != assetName)
{
importer.assetBundleName = assetName; //设置预设的AssetBundleName名称
//importer.SaveAndReimport();
}
//Debug.Log("主资源的路径:" + basePath);
if (ContainDependences) //把依赖资源分离打包
{
//获得他们的所有依赖,不过AssetDatabase.GetDependencies返回的依赖是包含对象自己本身的
string[] dps = AssetDatabase.GetDependencies(basePath); //获取依赖的相对路径Assets/...
Debug.Log(string.Format("There are {0} dependencies!", dps.Length));
//遍历设置依赖资源的Assetbundle名称,用哈希Id作为依赖资源的名称
for (int j = 0; j < dps.Length; j++)
{
Debug.Log(dps[j]);
//要过滤掉依赖的自己本身和脚本文件,自己本身的名称已设置,而脚本不能打包
if (dps[j].Contains(assetName) || dps[j].Contains(".cs"))
continue;
else
{
AssetImporter importer2 = AssetImporter.GetAtPath(dps[j]);
string dpName = AssetDatabase.AssetPathToGUID(dps[j]); //获取依赖资源的哈希ID
importer2.assetBundleName = "alldependencies/" + dpName;
//importer2.SaveAndReimport();
}
}
}
}
}
EditorUtility.ClearProgressBar(); //清除进度条
//接下来再全部打包
//BuildAllAssetBundles();
}
}
/// <summary>
/// 清除之前设置过的AssetBundleName,避免产生不必要的资源也打包
/// 因为只要设置了AssetBundleName的,都会进行打包,不论在什么目录下
/// </summary>
[MenuItem("AssetBundle/Clear All Assetbundle Name")]
public static void ClearAssetBundlesName()
{
string[] oldAssetBundleNames = AssetDatabase.GetAllAssetBundleNames();
for (int j = 0; j < oldAssetBundleNames.Length; j++)
{
AssetDatabase.RemoveAssetBundleName(oldAssetBundleNames[j], true);
}
}
}
//获取打包的平台
public class PlatformPath
{
/// <summary>
/// 获取打包的平台,根据平台设置打包的文件夹名称
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
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;
}
}
}
|
加载
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
|
using UnityEngine;
using System.Collections;
using System.IO;
using UnityEngine.UI;
using System;
public class LoadBundle : MonoBehaviour
{
void Start ()
{
StartCoroutine(GetData());
}
IEnumerator GetData() //服务端
{
//服务端用WWW加载 直接输入IP+对应的文件夹
WWW windowswww = new WWW("http://127.0.0.1/" + "PCAssetsResources/PCAssetsResources");
yield return windowswww;
AssetBundleManifest windowsasset = windowswww.assetBundle.LoadAsset("PCAssetsResources") as AssetBundleManifest;//这里对于新手来说特别重要!
//加载出对应的 AssetBundleManifest后才能再加载需要的Bundle文件 一定要注意
//AssetBundleManifest为路径目录的上一级文件夹 记录bundle的关联信息
WWW cubewww = new WWW("http://127.0.0.1/" + "PCAssetsResources/particle.unity3d");
//加载完总的依赖后,就可以进一步加载我们需要的资源包了
yield return cubewww;
GameObject obj = cubewww.assetBundle.LoadAsset("EasyAR_Startup") as GameObject;
//然后在加载完资源包后,就可以通过loadasset的方法去load出我们的资源
Instantiate(obj);
}
IEnumerator NoCacheingDownloadAsset() //本地端
{
//PC端用WWW加载 必须路径前加 file:// 此处一定要注意,是一个坑
WWW windowswww = new WWW("file://" + Application.dataPath + "/StreamingAssets/PCAssetsResources/PCAssetsResources");//Application.dataPath 当前工程目录
yield return windowswww;
AssetBundleManifest windowsasset = windowswww.assetBundle.LoadAsset("PCAssetsResources") as AssetBundleManifest;//这里对于新手来说特别重要!
//加载出对应的 AssetBundleManifest后才能再加载需要的Bundle文件 一定要注意
//AssetBundleManifest为路径目录的上一级文件夹 记录bundle的关联信息
WWW cubewww = new WWW("file://" + Application.dataPath + "/StreamingAssets/PCAssetsResources/particle.unity3d");//加载完总的依赖后,就可以进一步加载我们需要的资源包了
yield return cubewww;
GameObject obj = cubewww.assetBundle.LoadAsset("EasyAR_Startup") as GameObject;//然后在加载完资源包后,就可以通过loadasset的方法去load出我们的资源
Instantiate(obj);
}
}
|