原文地址:http://www.cnblogs.com/88999660/archive/2013/04/10/3011912.html
首先要鄙视下unity3d的文档编写人员极度不负责任,到发帖为止依然没有更新正确的示例代码。
// C# Example // Builds an asset bundle from the selected objects in the project view. // Once compiled go to "Menu" -> "Assets" and select one of the choices // to build the Asset Bundle using UnityEngine; using UnityEditor; using System.IO; public class ExportAssetBundles { [MenuItem("Assets/Build AssetBundle Binary file From Selection - Track dependencies ")] static void ExportResource () { // Bring up save panel string path = EditorUtility.SaveFilePanel ("Save Resource", "", "New Resource", "unity3d"); if (path.Length != 0) { // Build the resource file from the active selection. Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets); BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets); Selection.objects = selection; FileStream fs = new FileStream(path,FileMode.Open,FileAccess.ReadWrite); byte[] buff = new byte[fs.Length+1]; fs.Read(buff,0,(int)fs.Length); buff[buff.Length-1] = 0; fs.Close(); File.Delete(path); string BinPath = path.Substring(0,path.LastIndexOf('.'))+".bytes"; // FileStream cfs = new FileStream(BinPath,FileMode.Create); cfs.Write(buff,0,buff.Length); buff =null; cfs.Close(); // string AssetsPath = BinPath.Substring(BinPath.IndexOf("Assets")); // Object ta = AssetDatabase.LoadAssetAtPath(AssetsPath,typeof(Object)); // BuildPipeline.BuildAssetBundle(ta, null, path); } } [MenuItem("Assets/Build AssetBundle From Selection - No dependency tracking")] static void ExportResourceNoTrack () { // Bring up save panel string path = EditorUtility.SaveFilePanel ("Save Resource", "", "New Resource", "unity3d"); if (path.Length != 0) { // Build the resource file from the active selection. BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, path); } }
把打包的文件转换成了binary文件并多加了一个字节加密。
当bytes文件生成好后再选中它,使用"Assets/Build AssetBundle From Selection - No dependency tracking"再次打包。
using UnityEngine; using System.Collections; using System; public class WWWLoadTest : MonoBehaviour { public string BundleURL; public string AssetName; IEnumerator Start() { WWW www =WWW.LoadFromCacheOrDownload(BundleURL,2); yield return www; TextAsset txt = www.assetBundle.Load("characters",typeof(TextAsset)) as TextAsset; byte[] data = txt.bytes; byte[] decryptedData = Decryption(data); Debug.LogError("decryptedData length:"+decryptedData.Length); StartCoroutine(LoadBundle(decryptedData)); } IEnumerator LoadBundle(byte[] decryptedData){ AssetBundleCreateRequest acr = AssetBundle.CreateFromMemory(decryptedData); yield return acr; AssetBundle bundle = acr.assetBundle; Instantiate(bundle.Load(AssetName)); } byte[] Decryption(byte[] data){ byte[] tmp = new byte[data.Length-1]; for(int i=0;i1;i++){ tmp[i] = data[i]; } return tmp; } }
WWW.LoadFromCacheOrDownload的作用就是下载并缓存资源,要注意后面的版本号参数,如果替换了资源却没有更新版本号,客户端依然会加载缓存中的文件。
www.assetBundle.Load("characters",typeof(TextAsset)) as TextAsset //characters是加密文件的名字
AssetBundleCreateRequest acr = AssetBundle.CreateFromMemory(decryptedData);
这句是官网最坑爹的,AssetBundle.CreateFromMemory明 明返回的是AssetBundleCreateRequest官网却写得是AssetBundle,而且 AssetBundleCreateRequest是一个异步加载,必须用协程的方式加载官网也没有提到。跟多兄弟就倒在了这里
完。
原理这里要说明下,是这样子的,先把资源变成。unity3d格式,然后转成。bytes格式,再转成。unity3d格式,
加载的时候加载。unity3d格式,解析,然后变资源
我经过测试给出我的代码:
using UnityEngine; using System.Collections; using UnityEditor; using System.IO; public class assetPack : 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 + "/eScene.unity3d"; string[] levels = { "Assets/myScene.unity" }; //打包场景 BuildPipeline.BuildPlayer( levels, Path,BuildTarget.StandaloneWindows, BuildOptions.BuildAdditionalStreamedScenes); AssetDatabase.Refresh (); } [MenuItem("Custom Editor/Save Scene")] static void ExportScene() { // 打开保存面板,获得用户选择的路径 string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d"); if (path.Length != 0) { // 选择的要保存的对象 Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets); string[] scenes = { "Assets/myScene.unity" }; //打包 BuildPipeline.BuildPlayer(scenes, path, BuildTarget.StandaloneWindows, BuildOptions.BuildAdditionalStreamedScenes); } AssetDatabase.Refresh(); } [MenuItem("Custom Editor/Save Scene2")] static void ExportResource() { // Bring up save panel string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d"); if (path.Length != 0) { // Build the resource file from the active selection. Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets); BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets); Selection.objects = selection; } } [MenuItem("Custom Editor/Build AssetBundle From Selection - Track dependencies")] static void ExportResource2() { // Bring up save panel string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d"); if (path.Length != 0) { // Build the resource file from the active selection. Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets); BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets); Selection.objects = selection; } } [MenuItem("Custom Editor/Build AssetBundle Complited to bytes")] static void ExportResource5() { // Bring up save panel string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d"); if (path.Length != 0) { // Build the resource file from the active selection. Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets); BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets, BuildTarget.StandaloneWindows); Selection.objects = selection; FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite); byte[] buff = new byte[fs.Length + 1]; fs.Read(buff, 0, (int)fs.Length); buff[buff.Length - 1] = 0; Debug.Log("filelength:"+ buff.Length); fs.Close(); File.Delete(path); string BinPath = path.Substring(0, path.LastIndexOf('.')) + ".bytes"; FileStream cfs = new FileStream(BinPath,FileMode.Create); cfs.Write(buff, 0, buff.Length); Debug.Log("filelength:" + buff.Length); buff = null; cfs.Close(); } } [MenuItem("Custom Editor/Build AssetBundle From Selection Twice")] static void ExportResourceNoTrack() { // Bring up save panel string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d"); if (path.Length != 0) { // Build the resource file from the active selection. BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, path); } } }
加载部分
using UnityEngine; using System.Collections; public class loadnew : MonoBehaviour { public string filename; private string BundleURL; private string AssetName; IEnumerator Start() { BundleURL = "file://" + Application.dataPath +"/"+ filename+".unity3d"; Debug.Log("path:"+ BundleURL); WWW m_Download = new WWW(BundleURL); yield return m_Download; if (m_Download.error != null) { // Debug.LogError(m_Download.error); Debug.Log("Warning errow: " + "NewScene"); yield break; } TextAsset txt = m_Download.assetBundle.Load(filename, typeof(TextAsset)) as TextAsset; byte[] data = txt.bytes; byte[] decryptedData = Decryption(data); Debug.Log("decryptedData length:" + decryptedData.Length); StartCoroutine(LoadBundle(decryptedData)); } IEnumerator LoadBundle(byte[] decryptedData) { AssetBundleCreateRequest acr = AssetBundle.CreateFromMemory(decryptedData); yield return acr; AssetBundle bundle = acr.assetBundle; Instantiate(bundle.mainAsset); } byte[] Decryption(byte[] data) { byte[] tmp = new byte[data.Length - 1]; for (int i = 0; i < data.Length - 1; i++) { tmp[i] = data[i]; } return tmp; } void update() { } }