自己做备忘录笔记用,如有错误之处,还请阅读者指正。
Unity打包AssetBundle,并加载AssetBundle代码。其中有几个细节的地方,是做项目的时候踩的坑,这里做个备份。
using UnityEngine;
using UnityEditor;
///<summary>
///写一个Editor脚本,放在Editor文件夹里,作资源打包用。
///</summary>
public class BuildEditor : EditorWindow
{
private static string prefabDir = Application.dataPath + "/Prefabs";
[MenuItem("Window/Build Asset Bundles")]
static void BuildABs()
{
//先获取该目录下的所有文件。这里没有区分文件和文件夹的情况。如果再深入一点的话,就需要判断如果是文件夹的话,再循环。
//这里的prefabPaths都是全路径的字符串
string[] prefabPaths = Directory.GetFiles(prefabDir);
for (int i = 0; i < prefabPaths.Length; i++)
{
//如果它不是预制体,则不处理。
string extension = Path.GetExtension(prefabPaths[i]);
if (extension != ".prefab")
continue;
//Unity的目录斜杠跟Windows下的斜杠字符不一样,一个是左下,一个是右下。
//所以这里替换一下
prefabPaths[i] = prefabPaths[i].Replace(@"\","/");
//这里两行代码是去掉全路径前面的路径字符串,最后只得到像Assets/Prefabs/XXX.prefab这样的路径。
Match match = Regex.Match(prefabPaths[i], Application.dataPath);
prefabPaths[i] = "Assets" + prefabPaths[i].Substring(match.Length);
AssetImporter ai = AssetImporter.GetAtPath(prefabPaths[i]);
//获取到文件名字
string[] nameAndExtension = prefabPaths[i].Substring(prefabPaths[i].LastIndexOf("/") + 1).Split('.');
string prefabName = nameAndExtension[0];
//将prefab 的Name赋给AssetBundle的Name属性,这样就不需要用户每一个去设定prefab的assetbundle Name,但是也对Prefab的命名严格性有所增加。
if (ai != null && ai.assetBundleName != prefabName)
ai.assetBundleName = prefabName + ".data";
}
// Put the bundles in a folder called "ABs" within the Assets folder.
BuildPipeline.BuildAssetBundles("Assets/ABs", BuildAssetBundleOptions.None, BuildTarget.Android);
}
}
public class LoadAssetBundle:MonoBehaviour
{
//这里路径一定要带http://不然在手机端APP里会报找不到协议的问题:
//java.net.MalformedURLException: Protocol not found
string path = "http://10.1.33.40:8081/res/";
IEnumerator Load(string assetName)
{
WWW www = WWW.LoadFromCacheOrDownload(curPath,0);
yield return www;
if(www.isDone && www.assetBundle != null)
{
if (go != null)
Destroy(go);
yield return 1;
go = Instantiate(www.assetBundle.LoadAsset(assetName)) as GameObject;
go.transform.position = new Vector3(0,0,1.0f);
//release unused assets.
//Resources.UnloadUnusedAssets();
//这里使用完这个assetBundle之后,要么卸载掉,要么保存起来到一个变量中去。不然下一次再加载同一个
//assetBundle的时候,会报错,说重复加载了assetBundle。
www.assetBundle.Unload(false);
}
if (!string.IsNullOrEmpty(www.error))
VRDebug.Log(www.error);
if(www.assetBundle == null)
{
VRDebug.Log("Download asset is null.");
}
}
}