原文地址: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 != ) {
// 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+];
fs.Read(buff,,(int)fs.Length);
buff[buff.Length-] = ;
fs.Close();
File.Delete(path); string BinPath = path.Substring(,path.LastIndexOf('.'))+".bytes";
// FileStream cfs = new FileStream(BinPath,FileMode.Create);
cfs.Write(buff,,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 != ) {
// 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,); 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-];
for(int i=;i<data.Length-;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 != )
{
// 选择的要保存的对象
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 != )
{
// 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 != )
{
// 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 != )
{
// 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 + ];
fs.Read(buff, , (int)fs.Length);
buff[buff.Length - ] = ;
Debug.Log("filelength:"+ buff.Length);
fs.Close();
File.Delete(path); string BinPath = path.Substring(, path.LastIndexOf('.')) + ".bytes";
FileStream cfs = new FileStream(BinPath,FileMode.Create);
cfs.Write(buff, , 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 != )
{
// 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 - ];
for (int i = ; i < data.Length - ; i++)
{
tmp[i] = data[i];
}
return tmp; } void update()
{ }
}