AssetBundle资源包资料搜集。。备忘。。

 


=========================以下为更新===========================



[脚本]制作unity3d动态加载资源文件*.unity3d

 

1、在unity3d项目(Project)面板的Editor目录下,新建C# script,取名为ExportAssetBundles,  
2、复制unity3d的帮助文档BuildPipeline.BuildAssetBundle中的代码到ExportAssetBundles.cs中。  

==看完该节,请续看下方的修正篇==(该节博文   图片在编辑模式下是可见的,原址忘了,见谅)===

ExportAssetBundles.cs代码如下:

using UnityEngine;

using UnityEditor;

public class ExportAssetBundles {

    [MenuItem("Export/Build AssetBundle 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;

        }

    }

    [MenuItem("Export/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);

        }

    }

}

我们不需要解释这个类这个类在创建完成之后我们会发现我们的导航栏里多了

17-01.png

这个东西这是导出Unity3d格式的工具

但是在导出之前我们需要把我们创建的组件放到prefeb里面之后点中prefeb选择上述第一个选项,弹出对话框,选择保存的位置。Ok 这样一个unity3d格式的文件就导出成功了为我们下面的远端加载奠定了基础

这里我们需要注意:

在流式加载之前我们首先要解决我们的跨域访问的问题

解决方案如下:

17-02.png

17-03.png

好了这样我们的跨域访问设置好了。

下面我们要做的就是在远端访问这个服务器把我们需要的东西下载下来:

代码详情:(不需要理解会用就行)

using UnityEngine;

using System.Collections;

public class LoadTank : MonoBehaviour {

private AssetBundle ab;

// Use this for initialization

void Start () {

StartCoroutine(LoadUnity("http://192.168.1.103:8000/u3dpag/tank.unity3d"));

}

// Update is called once per frame

void Update () {

}

IEnumerator LoadUnity(string url)

{

WWW download=new WWW(url);

yield return download;

ab=download.assetBundle;

if (ab!=null) {

print("Success import");

GameObject tankObj = (GameObject)Instantiate(download.assetBundle.mainAsset);

tankObj.transform.position = new Vector3(0,0,0);

}else{

print("download falls");

}

}

}

新创建一个场景 把上述类与我们的摄像机绑定 好了运行。我们会看到我们成功加载了放在服务端的我们已经成功的导成Unity3d格式的组件了 。很神奇把。。。快试试吧!


=========修正篇=========

unity3d加密资源并缓存加载

阅读340次 2013/4/10 11:01:06
-

首先要鄙视下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;i<data.Length-1;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格式的导出与加载


1、单一文件创建unity3d

using UnityEngine; 
using UnityEditor; 
using System.IO; 
public class BuildAssetBundlesFromDirectory { 
	[@MenuItem("Asset/Build AssetBundles From Directory of Files")]//生成菜单 
	static void ExportAssetBundles () { // Get the selected directory //获取选择的目录 
		string path = AssetDatabase.GetAssetPath(Selection.activeObject); 
		Debug.Log("Selected Folder: " + path); 
		if (path.Length != 0) { 
			path = path.Replace("Assets/", ""); 
			string [] fileEntries = Directory.GetFiles(Application.dataPath+"/"+path); 
			foreach(string fileName in fileEntries) { 
				string filePath = fileName.Replace("\\","/"); 
				int index = filePath.LastIndexOf("/"); 
				filePath = filePath.Substring(index+1); 
				Debug.Log("filePath:"+filePath); 
				string localPath = "Assets/" + path+"/"
				if (index > 0) localPath += filePath; 
				Object t = AssetDatabase.LoadMainAssetAtPath(localPath); 
				if (t != null) { Debug.Log(t.name); 
				string bundlePath = "Assets/" + path + "/" + t.name + ".unity3d"
				Debug.Log("Building bundle at: "+ bundlePath); // Build the resource file from the active selection. //从激活的选择编译资源文件 
				BuildPipeline.BuildAssetBundle (t, null, bundlePath, BuildAssetBundleOptions.CompleteAssets); 
			
		
	
}
 

 

 说明:string filePath = fileName.Replace("\\","/");  把“\”转化成“/”。把以上代码的脚本放到一个文件夹里面(须放在Assets\Editor目录下面),选中该文件夹,再点击菜单栏上的按钮"Asset/Build AssetBundles From Directory of Files",就成功转成unity3d格式了。

2、单一文件unity3d格式的加载

function Start () { 
	var www = new WWW ("file:///"+Application.dataPath+"/resourse/Cube.unity3d");//Windows 
	yield www; 
	Instantiate(www.assetBundle.mainAsset); 
}

 

function Start () { 
	var www = WWW.LoadFromCacheOrDownload("http://210.30.12.33:8080/YangChun/file/Cube.unity3d",5); //webPlayer 
	yield www; 
	if (www.error != null) { 
		Debug.Log (www.error); 
		return
	
	Instantiate(www.assetBundle.mainAsset); 
}

 

3、场景转化成unity3D格式

 

@MenuItem ("Build/BuildScene"
static function MyBuild(){ 
	var levels : String[] = ["Assets/main.unity"]; //main为场景名称 
	BuildPipeline.BuildStreamedSceneAssetBundle( levels, "test.unity3d", BuildTarget.WebPlayer);//BuildTarget.Andrdoid “test.unity3d”为生成的文件名称 
 } //或者 
 @MenuItem ("Build/BuildScene"
static function MyBuild(){ 
	BuildPipeline.BuildPlayer(["Assets/main.unity"],"test.unity3d",BuildTarget.WebPlayer, BuildOptions.BuildAdditionalStreamedScenes); 
}

说明:默认生成的文件是在工程根目录下面,同样此文件得放在Assets\Editor目录下面;BuildTarget,转化成不同的平台,这个根据实际需要设置即可。

 

4、unity3D场景文件加载

 

function Start () { 
	// Download compressed scene. If version 5 of the file named "test.unity3d" was previously downloaded and cached
	// Then Unity will completely skip the download and load the decompressed scene directly from disk. 
	//下载压缩的场景。如果名为test.unity3d的文件版本为5,预先下载并缓存。 
	//然后Unity将完全跳过下载并直接从磁盘加载解压的场景。 
	var download = WWW.LoadFromCacheOrDownload ("file:///"+Application.dataPath + "/test.unity3d", 5); 
	// var download = WWW.LoadFromCacheOrDownload ("http://myWebSite.com/test.unity3d", 5); 
	print(Application.dataPath + "/test.unity3d"); 
	yield download; // Handle error 
	if (download.error != null) { Debug.LogError(download.error); return; } 
	// In order to make the scene available from LoadLevel, we have to load the asset bundle. 
	// The AssetBundle class also lets you force unload all assets and file storage once it is no longer needed. 
	//为了使场景LoadLevel可用,必须加载资源包 
	//AssetBundle类,还可以强制卸载所有的资源和文件存储,一旦不再需要。 
	var bundle = download.assetBundle; // Load the level we have just downloaded //加载刚才下载的场景 
	Application.LoadLevel ("main"); 
}

 


==========实战篇完=============


资源包问答 AssetBundles FAQ



  1. What are AssetBundles? 什么是资源包?
  2. What are they used for? 它们是用来做什么的?
  3. How do I create an AssetBundle? 如何建立一个AssetBundles?
  4. How do I use an AssetBundle? 如何使用一个AssetBundles?
  5. How do I use AssetBundles in the Editor? 如何在编译器中使用AssetBundle?
  6. How do I cache AssetBundles? 如何缓存AssetBundle?
  7. Are AssetBundles cross-platform? AssetBundle是否兼容所有的平台?
  8. How are assets in AssetBundles identified ? AssetBundles中的资源是如何被识别的?
  9. Can I reuse my AssetBundles in another game? 能重用其他游戏中的AssetBundle么?
  10. Will an AssetBundle built now be usable with future versions of Unity? 现在生成的AssetBundle是否可以用在未来版本的Unity 中?
  11. How can I list the objects in an AssetBundle? 如何列举一个AssetBundle中的物体?

  1. What are AssetBundles? 什么是资源包?

AssetBundles are a collection of assets, packaged for loading at runtime. With Asset Bundles, you can dynamically load and unload new content into your application. AssetBundles can be used to implement post-release DLC.

AssetBundles 是一组为运行时载入而打包组成的资源的集合。通过AssetBundles,你可以为你的应用动态的加载和卸载新的资源。AssetBundles可以用来实现DLC的发布。(注:DLC—— Downloadable Content 可下载资料片)。

  1. What are they used for? 他们是用来做什么的?

They can be used to reduce the amount of space on disk used by your game, when first deployed. It can also be used to add new content to an already published game.

他们可以用来减少你的游戏第一次部署时所占的硬盘空间大小。它也经常被用来在游戏发布后下载新的内容。

  1. How do I create an AssetBundle? 如何建立一个资源包?

To create an AssetBundle you need to use the BuildPipeline editor class. All scripts using Editor classes must be placed in a folder named Editor, anywhere in the Assets folder. Here is an example of such a script in C#:

创建一个新的AssetBundles需要使用到BuildPipline编译器类。所有被使用的编译器类必须被放置在Assets/Editor文件夹内。下面是一个C#脚本的例子:

 

using UnityEngine;
using UnityEditor;

public class ExportAssetBundles {
    [MenuItem("Assets/Build AssetBundle")]
        static void ExportResource () {
            string path = "Assets/myAssetBundle.unity3d";
            Object[] selection =  Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
            BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets);
        }
    }
}

An Editor script does not need to be applied to a GameObject, it is instead used by the Editor. This previous example will create a new item in the Assets menu of your editor called Build AssetBundle.

Editor 脚本不必将其部署在一个GameObject上,他能自动被编译器使用。上面那个例子可以在Asset菜单上建立一个叫做Build AssetBundle的选项。

To use this example:

Create a C# script file named ExportAssetBundles.cs, inside an folder named Editor, in the Project View. Select the Asset or Assets in your project folder that you wish to make into an AssetBundle. Select Build AssetBundle from the Assets menu. Click Save to create the AssetBundle. The first line of the ExportResource function sets the path of your AssetBundle. The next line sets the selection to be made into an AssetBundle as the objects selected in the Project window.

如要使用这个例子:

在工程视图的Editor文件夹内建立一个名为ExportAssetBundles.cs的C#脚本。 选择一个或一些你工程文件夹内,你希望制作成AssetBundle的资源; 点击Asset菜单中的Build AssetBundle按钮,点击Save建立AssetBundle。 ExportResource函数的第一行设置了你输出AssetBundle的路径。 之后的一行选择了将选择的(资源)制作称为在所选工程路径下的一个AssetBundle。

The BuildAssetBundle function is the line that creates the AssetBundle and saves it to the specified location. The first parameter specifies the mainAsset, which is a special Asset that can be obtained directly with the mainAsset property when loading Assets from the AssetBundle. It is not mandatory to set a main Asset, if this is not going to be used you can use null for the parameter. The second parameter is the array of objects that will make up the AssetBundle. The third parameter is the location on disk that the AssetBundle will be saved to. The final parameter are the build flags or options used when building AssetBundles. The bitwise OR ( | ) combines the options passed to build the AssetBundles. In this example BuildAssetBundleOptions.CollectDependencies sets it to include other Assets referenced by the objects and BuildAssetBundleOptions.CompleteAssets make sure that assets are completely included.

BuildAssetBundle 函数所在的那一行的作用是制作那个AssetBundle并将其保存在指定的位置。第一个参数指定了mainAsset。mainAsset是一个可以在载入时直接从AssetBundle中包含的资源。这个参数并非必须设置的,如果你没有用到它你可以将其设置成null。第二个参数是你要制成AssetBundle的一组物体。第三个参数是你的AssetBundle即将保存到的本地硬盘位置。最后一个参数是你建立AssetBundle时使用的一系列标识符。中间的位操作符OR( | )将标识符合并,之后传送给建立AssetBundle的过程。在这个例子中BuildAssetBundleOptions.CollectDependencies设置包含被该物体所引用的其他资源,BuildAssetBundleOptions.CompleteAssets确保这些资源被完全引用。

Building AssetBundles should be a pre-publish step which happens only once and with a single function call, for example, with a Menu Item that builds all the AssetBundles. As you develop your application you should write helper scripts that can build all your AssetBundles for a target platform with a single click or in batchmode without user intervention.

建立AssetBundles需要有一个发布前的步骤:这个步骤只产生一次并且只使用一次简单的函数调用。比如,使用一个菜单选项就可以建立所有的AssetBundles。当你开发你的应用程序时,你需编写一些帮助脚本。那样你通过一次简单的点击或批处理,就可以为某种目标平台建立你所有的AssetBundles,而不需要其他人的介入。

There are also other function to create AssetBundles. You can read more about this here: http://docwiki.hq.unity3d.com/index.php?n=Main.BuildingAssetBundles

这里还有一些其他的建立AssetBundles的方式。更多细节参考http://docwiki.hq.unity3d.com/index.php?n=Main.BuildingAssetBundles

  1. How do I use an AssetBundle? 如何使用一个资源包?

There are two main steps involved when working with AssetBundles. The first step is to download the AssetBundle from a server or disk location. This is done with the WWW class. The second step is to load the Assets from the AssetBundle, to be used in the application. Here is an example C# script:

当你使用AssetBundles时有两个主要步骤。第一步是从服务器将AssetBundles下载至本地硬盘。这一步使用WWW类来完成。第二步是从AssetBundle中载入资源,并将其使用在应用内。下面是一个C#脚本的例子:

 
using UnityEngine;
using System.Collections;

public class BundleLoader : MonoBehaviour{
    public string url;
    public int version;
    public IEnumerator LoadBundle(){
        using(WWW www = WWW.LoadFromCacheOrDownload(url, version){
            yield return www;
            AssetBundle assetBundle = www.assetBundle;
            GameObject gameObject = assetBundle.mainAsset as GameObject;
            Instantiate(gameObject );
            assetBundle.Unload(false);
        }
    }
    void Start(){
        StartCoroutine(LoadBundle());
    }
}

This script is added to a GameObject as Component. The AssetBundle is loaded in the following way:

将该脚本当做组件添加进一个游戏物体(GameObject)。这个AssetBundles是使用如下方式进行加载的:

  • The url and version values need to be set in the Inspector prior to running this script. The url is the location of the AssetBundle file, usually a server on the Internet. The version number allows the developer to associate a number to the AssetBundle when written to the cache in disk. When downloading an AssetBundle Unity will check if the file already exists in the cache. If it does, it compare the version of the stored asset with the version requested. If it is different then the AssetBundle will be redownloaded. If it's the same, then it will load the AssetBundle from disk and avoid having to redownload the file. Please refer to the WWW.LoadFromCacheOrDownload function in the scripting reference for more information about these parameters. 
    url 和 version的值需要在预先在所运行脚本的检视器中设置。url是AssetBundle文件的地址,通常是一个在网上的服务器。version允许开发者在将AssetBundle写入磁盘缓存时为其设置的一个版本参数。当下载一个AssetBundle时,unity会自动检测该AssetBundle是否已经在缓存中存在。如果已经存在,他将对比请求和存储的两份version值。如果对比结果不同,则该AssetBundle将重新下载。如果对比结果相同,那他将会从磁盘中载入(以避免重新下载该文件)。关于参数的详细内容请查阅在脚本手册中的WWW.LoadFromCacheOrDownload函数。
  • When the Start function of this script is called, it will start loading the AssetBundle by calling the function as a Coroutine.The function will yield on the WWW object as it downloads the AssetBundle. By using this, the function will simply stop in that point until the WWW object is done downloading, but it will not block the execution of the rest of the code, it yields until it is done. 
    当Start函数被执行时,他将会通过调用一个作为Coroutine的函数开始下载AssetBundles。这个函数将会在WWW 类下载AssetBundle时返回。通过使用这个方式,这个函数能便捷的在WWW下载时中断,直到WWW类下载完成。但是他并不会阻塞其他代码的执行,用yield可以让函数傲娇一下~但不会粗暴地拒绝剩下的代码,而是会在开完小差之后再回来调教它们。
  • Once the WWW object has downloaded AssetBundle file, the .assetBundle property is used to retrieve an AssetBundle object. This object is the interface to load objects from the AssetBundle file. 
    当WWW类完成AssetBundle文件的下载后,.assetBundle成员就可以用来产生一个AssetBundle的物体。这个物体是通过AssetBundle文件载入资源的接口。
  • In this example a reference to a prefab in the AssetBundle is retrieved from the AssetBundle using the .mainAsset property. This property is set when building the AssetBundle passing an Object as the first parameter. The main asset in the AssetBundle can be used to store a TextAsset with a list of objects inside the AssetBundle and any other information about them. 
    在这个例子中定义了一个AssetBundle类型的预制,他是使用.mainAsset成员变量重建的。mainAsset成员是由之前建立AssetBundles时传递的第一个参数设置的。这个AssetBundle的mainAsset成员可以存储一个TextAsset类型,在TextAsset类型内可以定义一个列表用以保存其他物体的信息。

Please note that for simplicity the previous example is not doing any safety checks. Please look at the code here for a more complete example.

请注意,为简单起见,前面的例子中,没有做任何安全检查。请看看这里的代码更完整的范例。

  1. How do I use AssetBundles in the Editor? 如何在编译器中使用AssetBundle?

As creating applications is an iterative process, you will very likely modify your Assets many times, which would require rebuilding the AssetBundles after every change to be able to test them. Even though it is possible to load AssetBundles in the Editor, that is not the recommended workflow. Instead, while testing in the Editor you should use the helper function Resources.LoadAssetAtPath to avoid having to use and rebuild AssetBundles. The function lets you load the Asset as if it were being loaded from an AssetBundle, but will skip the building process and your Assets are always up to date.

当你使用快速迭代(敏捷开发?)创造你的应用时,你也许会多次更改你的资源(Assets),这样就需要你在每次修改后重建你的AssetBundle来测试他们。尽管如此,工作流程中仍然不推荐在编译器中载入AssetBundle。一个替代方案是:当需要在编译器中测试时,你需要使用一个辅助函数Resources.LoadAssetAtPath来避免重建AssetBundles。这个函数让你能够载入需要从AssetBundle载入的资源,但是可以跳过重建过程而且你的资源也可以保持最新。

The following is an example helper script, that you can use to load your Assets depending on if you are running in the Editor or not. Put this code in C# script named AssetBundleLoader.cs:

下面是一个辅助函数脚本。你是否使用这个脚本来载入你的资源取决于你是否在使用编译器运行。将这些代码放在一个名为AssetBundleLoader.cs的C#脚本中。

 
using UnityEngine;
using System.Collections;

public class AssetBundleLoader {
    public Object Obj; // The object retrieved from the AssetBundle

    public IEnumerator LoadBundle<T> (string url, int version, string assetName, string assetPath) where T : Object {
        Obj = null;
#if UNITY_EDITOR
        Obj = Resources.LoadAssetAtPath(assetPath, typeof(T));
        if (Obj == null)
            Debug.LogError ("Asset not found at path: " + assetPath);
        yield break;
#else

        WWW download;
        if ( Caching.enabled )  {       
            while (!Caching.ready)
                yield return null;
           download = WWW.LoadFromCacheOrDownload( url, version );
        }
        else {
            download = new WWW (url);
        }

        yield return download;
        if ( download.error != null ) {
            Debug.LogError( download.error );
            download.Dispose();
            yield break;
        }

        AssetBundle assetBundle = download.assetBundle;
        download.Dispose();
        download = null;

        if (assetName == "" || assetName == null)
        Obj = assetBundle.mainAsset;
        else
            Obj = assetBundle.Load(assetName, typeof(T));

        assetBundle.Unload(false);
#endif
    }
}

We can now use the AssetBundleLoader script to load an Asset from an AssetBundle if we are running the built application or load the Asset directly from the Project folder if running in the Editor:

我们现在可以在运行建立好的应用时,使用AssetBundleLoader脚本从AssetBundle中或者直接从工程文件夹中载入资源

using UnityEngine;
using System.Collections;

public class ExampleLoadingBundle : MonoBehaviour {
    public string url = "http://www.mygame.com/myBundle.unity3d"; // URL where the AssetBundle is
    public int version = 1; // The version of the AssetBundle

    public string assetName = "MyPrefab"; // Name of the Asset to be loaded from the AssetBundle
    public string assetPath; // Path to the Asset in the Project folder

    private Object ObjInstance; // Instance of the object
    void Start(){
        StartCoroutine(Download());
    }

    IEnumerator Download () {
        AssetBundleLoader assetBundleLoader = new AssetBundleLoader ();
        yield return StartCoroutine(assetBundleLoader.LoadBundle <GameObject> (url, version, assetName, assetPath));
        if (assetBundleLoader.Obj != null)
            ObjInstance = Instantiate (assetBundleLoader.Obj);
    }

    void OnGUI(){
        GUILayout.Label (ObjInstance ? ObjInstance.name + " instantiated" : "");
    }
}

The previous script should be saved to a file named ExampleLoadingBundle.cs inside the Assets folder. After setting the public variables to their correct values and running it, it will use the AssetBundleLoader class to load an Asset. It is then instantiated and this will be shown by using the GUI.

上面的脚本需要被保存在Asset文件夹下一个名为ExampleLoadingBundle.cs的脚本中。在设置了正确的公共变量并且运行他的时候,他将使用AssetBundleLoader类加载一个资源。之后他会通过GUI显示出来。

  1. How do I cache AssetBundles? 如何缓存资源包?

You can use WWW.LoadFromCacheOrDownload which automatically takes care of saving your AssetBundles to disk. Be aware that on the Webplayer you are limited to 50MB in total (shared between all webplayers). You can buy a separate caching license for your game if you require more space.

你可以使用自动适配的WWW.LoadFromCacheOrDownload函数将AssetBundle保存至磁盘。需要注意的是,在WebPlayer中有50MB的缓存上限限制(所有的webplayers共享)。如果你需要更多的空间,你可以为你的游戏单独购买一份独立缓存许可。

  1. Are AssetBundles cross-platform? 资源包是否兼容所有的平台?

AssetBundles are compatible between some platforms. Use the following table as a guideline.

一些平台之间的AssetBundles兼容,使用下表作为指导。

Platform compatibility for AssetBundles
 StandaloneWebplayeriOSAndroid
EditorYYYY
StandaloneYY  
WebplayerYY  
iOS  Y 
Android    Y

For example, a bundle created while the Webplayer build target was active would be compatible with the editor and with standalone builds. However, it would not be compatible with apps built for the iOS or Android platforms.

举个例子,一个Webplayer建立的target可以被Editor和Standalone 所兼容,但是不会被ISO或Android平台兼容。

  1. How are assets in AssetBundles identified? 资源包中的资源是如何被识别的?

When you build AssetBundles the assets are identified internally by their filename without the extension. For example a Texture located in your Project folder at "Assets/Textures/myTexture.jpg" is identified and loaded using "myTexture" if you use the default method. You can have more control over this by supplying your own array of ids (strings) for each object when Building your AssetBundle with BuildPipeline.BuildAssetBundleExplicitAssetNames.

当你建立一个AssetBundles的时候这些资源已经通过他们的文件名(不含扩展名)在内部完成识别。比如,如果你使用默认方式定义一个位于你工程目录”Assets/Textures/myTexture.jpg”的贴图,那么他会使用”myTexture”被识别加载。你可以在建立AssetBundle的时候使用BuildAssetBundleOptions.CollectDependencies选项为每个物体提供你自己的id(string)以方便控制。

  1. Can I reuse my AssetBundles in another game? 能重用其他游戏中的AssetBundle么?

AssetBundles allow you to share content between different games. The requirement is that any Assets which are referenced by GameObjects in your AssetBundle must either be included in the AssetBundle or exist in the application (loaded in the current scene). To make sure the referenced Assets are included in the AssetBundle when they are built you can pass the BuildAssetBundleOptions.CollectDependencies option.

AssetBundle允许你在不同游戏间共享内容。但是那些GameObject所引用的资源必须在你的AssetBundle中或者在你的你的应用中存在(已经在当前场景中被载入)。你可以在建立AssetBundle时使用BuildAssetBundleOptions.CollectDependencies 确保你引用的资源已经被包含在AssetBundle中。

  1. Will an AssetBundle built now be usable with future versions of Unity? 现在生成的AssetBundle是否可以用在未来版本的Unity 中?

AssetBundles can contain a structure called a type tree which allows information about asset types to be understood correctly between different versions of Unity. On desktop platforms, the type tree is included by default but can be disabled by passing the BuildAssetBundleOptions.DisableWriteTypeTree to the BuildAssetBundle function. Webplayers intrinsically rely on the type tree and so it is always included (ie, the DisableWriteTypeTree option has no effect). Type trees are never included for mobile and console asset bundles and so you will need to rebuild these bundles whenever the serialization format changes. This can happen in new versions of Unity. (Except for bugfix releases) It also happens if you add or remove serialized fields in monobehaviour's that are included in the asset bundle. When loading an AssetBundle Unity will give you an error message if the AssetBundle must be rebuilt.

AssetBundles可以包含一个被称为类型树的结构,该结构所保存的信息可以用来确保不同版本下的Unity都能理解保重的资源类型。在桌面平台中,这个类型树是被默认建立的,但是可以在调用BuildAssetBundle函数时使用 BuildAssetBundleOptions.DisableWriteTypeTree参数使其失效。从本质上讲Webplayer 本身就依赖于类型树,所以总是包含类型树(也就是说,DisableWriteTypeTree选项本身无效)。类型树永远不被移动平台和控制台资源包所包含,并且你需要在你序列化格式更改时重建。在新版本的unity中这也会发生(除非是某些修复bug的版本)。这件事也同样发生在你尝试添加或移除已经包含在assetBundle中的已被序列化的monobehaviour类的时候。如果你的AssetBundle必须被重建,在下载AssetBundle时Unity会发送一条错误的信息。

  1. How can I list the objects in an AssetBundle? 如何列举一个AssetBundle中的物体?

You can use AssetBundle.LoadAll to retrieve an array containing all objects from the AssetBundle. It is not possible to get a list of the identifiers directly. A common workaround is to keep a separate TextAsset to hold the names of the assets in the AssetBundle.

你可以使用AssetBundle.LoadAll重建一个包含AssetBundle内所有物体的队列。直接获取一个定义列表是不可能的。一个通常的做法是维护一个包含所有资源的TextAsset类型的物体名单。

back to AssetBundles Intro

页面最后更新:2012-9-13



=======================以上为更新===============================

 

 

AssetBundles are files which you can export from Unity to contain assets of your choice. These files use a proprietary compressed format and can be loaded on demand in your application. This allows you to stream content like models, textures, audio clips and even entire scenes separately from the scene in which they will be used. They have been designed to make it easy to download content to your application.

在一些大型的网络游戏,或者加载比较多的一些场景时,如果要等待所有模型,贴图等各种资源文件加载完毕才能执行游戏,对用户将会是一个很头大的事情。所以就需要用到动态加载,即AssetBundles。比如玩家在进入游戏时先加载一些周围的场景文件,这样不仅可以提高速度还可以减少内存资源的消耗。

AssetBundles是可以把unity3d中你所创建的文件或任何资源导出的一种文件格式,这些文件导出后使用的是一种特定的文件格式(.Unity3d),这些特定格式的文件能在需要的时候加载到场景中。而这些特定的文件格式可以是模型,贴图,声音文件甚至是场景文件,它们是先前就被设计好的文件,所以很容易就可以被下载到你所建立的游戏或场景中来。

AssetBundles can contain any kind of asset type recognized by Unity, as determined by the filename extension. If you want to include files with custom binary data, then you must rename those files to have ".bytes" as the extension. Unity will import these files as TextAssets.

AssetBundles 可以是任意类型的文件只要是unity3d能识别的资源文件格式,识别主要是以文件扩展名为准,比如.prefab等等。当然如果你想包含自定义的二进制文件,需要命名这些文件为以".bytes"为后缀,Unity将会把这些文件导成TextAssets。

For some sample code showing how to use asset bundles, see the AssetBundles Example Project

如果想了解更多关于代码如何实现,可以参考 AssetBundles Example Project

Creating AssetBundles 创建资源包

There are three class methods you can use to build AssetBundles: BuildPipeline.BuildAssetBundle, BuildPipeline.BuildStreamedSceneAssetBundle and BuildPipeline.BuildAssetBundleExplicitAssetNames..

有三个类方法可以用来构建资源包:BuildPipeline.BuildAssetBundle,BuildPipeline.BuildStreamedSceneAssetBundle BuildPipeline.BuildAssetBundleExplicitAssetNames.

  • BuildPipeline.BuildAssetBundle allows you to build AssetBundles of any type of asset.
    可以构建任意类型资源的资源包。【创建一个压缩好的包含Assets下的所有资源文件.unity3d。可以包含是项目目录下的任意资源,而把所有的资源压缩成一个.unity3d的文件,这个文件包括所有的预置物体(prefabs),纹理贴图(textures),模型,动画。使用AssetBundle.mainAsset这个函数可以很方便的让你指定一个定义好的物体。被压缩的资源储存在pathName. Options,会自动的允许用户包含相关的或者需要用到的】
  • BuildPipeline.BuildStreamedSceneAssetBundle is used when you want to include only scenes to be streamed and loaded as the data becomes available.
    用来当你希望只包括流场景,使数据加载变为可用。【建立一个或多个场景,这些场景所需要的所有资源将被压缩入资源包,即asset bundle里面。资源包中的场景文件可以在任何平台上建立,而且这些文件往往是以一个单一的unity3d文件格式被用来创建。使用WWW类可以下载场景文件。当场景文件被下载好可以使用WWW.LoadFromCacheOrDownload来加载下载好的场景文件。】
  • BuildPipeline.BuildAssetBundleExplicitAssetNames is the same as BuildPipeline.BuildAssetBundle but has an extra parameter to specify a custom string identifier (name) for each object.
    和BuildPipeline.BuildAssetBundle类似,但是有额外的参数来指定每个物体的自定义的字符串(名字)。【建立一个自定义名字的资源包方法: 创建一个包含所有资源的一个压缩好的unity3d文件。AssetBundle可以包括任何项目目录下的资源文件。在assetNames参数中提供一个与资源数目相同大小的字符串数组。在资源数组中存储的信息与资源文件名相同,可以传递AssetBundle.Load去加载一个指定的资源。使用BuildAssetBundle时,只需使用资源的路径名。压缩好的资源包文件将会被储存在pathName. Options,允许用户自动包含与之相关的或者总是包含完整的资源去代替确切的参照物体。】

当使用上面的三个函数做完准备工作,我们现在就需要去下载这些资源然后加载它们。

Downloading AssetBundles 下载资源包

The recommended way to download AssetBundles is to use WWW.LoadFromCacheOrDownload. Once the download is complete you can retrieve the AssetBundle with the assetBundle property. For example:

推荐使用WWW.LoadFromCacheOrDownload方法用来下载资源。当下载完成你就可以重新得到该资源的相关属性,例如:

string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
    // Start a download of the given URL
	// 从指定路径下载
    WWW www = WWW.LoadFromCacheOrDownload (url, 1);

    // Wait for download to complete
	// 等待下载完成
    yield return www;

    // Load and retrieve the AssetBundle
	// 加载并取回资源包
    AssetBundle bundle = www.assetBundle;
}

When you access the .assetBundle property the downloaded data is extracted and the AssetBundle object is created. At this point, you are ready to load the objects contained in the bundle. The second parameter passed to LoadFromCacheOrDownload specifies which version of the AssetBundle to download. LoadFromCacheOrDownload will download the AssetBundle if it doesn't exist in the cache or if it exists but is associated with a version that is lower than the one requested. Otherwise the AssetBundle will be loaded from cache.

以上代码中的url是资源路径的下载地址,首先使用LoadFromCacheOrDownload下载资源,括号中的url是路径,1代表版本号,当等待下载完成后即可加载相关资源。

当资源包中的对象创建好之后,就可以激活下载好的资源被解压。到这里,就需要用户去加载包含在资源包器中的对象。LoadFromCacheOrDownload函数中的第二个参数是指定下载资源的版本号。如果在存储器中的资源没有被下载或者资源下载了但是比需要资源的版本号低,LoadFromCacheOrDownload函数将会下载资源到资源包中。否则资源包其将会直接从存储器中加载。

Loading and unloading objects from an AssetBundle 从资源包加载和卸载对象

Having created an AssetBundle object from the downloaded data, you can load the objects contained in it using three different methods:AssetBundle.Load,AssetBundle.LoadAsync and AssetBundle.LoadAll.

如果下载数据已经建立了资源包,你就可以使用这三个不同的函数来加载物体了: AssetBundle.Load, AssetBundle.LoadAsync AssetBundle.LoadAll.

  • AssetBundle.Load will load an object using its name identifier as a parameter. The name is the one visible in the Project view. You can optionally pass an object type as an argument to the Load method to make sure the object loaded is of a specific type.
    AssetBundle.Load会加载物体,使用该物体的名字作为识别的参数。名字可以在Unity3d中Project view看到。你可以自由选择去传递对象变量的类型来确认该加载对象是否是被指定的类型。
  • AssetBundle.LoadAsync works the same as the Load method described above but it will not block the main thread while the asset is loaded. This is useful when loading large assets or many assets at once to avoid pauses in your application.
    AssetBundle.LoadAsync 与AssetBundle.Load 函数相类似,但是当资源加载时它不会阻碍主线程。如果同时要加载比较大的资源或者很多资源时,这个函数会比较有用,它可以避免程序的暂停,因为它会同步加载。
  • AssetBundle.LoadAll will load all the objects contained in your AssetBundle. As with AssetBundle.Load, you can optionally filter objects by their type.
    AssetBundle.LoadAll 顾名思义这个函数是用来加载所有在你资源包中的对象。作为AssetBundle.Load这个函数,你可以随意用该对象的类型去过滤。

To unload assets you need to use AssetBundle.Unload. This method takes a boolean parameter which tells Unity whether to unload all data (including the loaded asset objects) or only the compressed data from the downloaded bundle. If your application is using some objects from the AssetBundle and you want to free some memory you can pass false to unload the compressed data from memory. If you want to completely unload everything from the AssetBundle you should pass true which will destroy the Assets loaded from the AssetBundle.

使用AssetBundle.Unload这个函数可以卸载加载好的资源,这个函数有一个布尔值的参数是用来告诉Unity是否要卸载所有的数据(包含加载的资源对象)或者只是已经下载过的被压缩好的资源数据。如果要在资源包中从你的应用程序要使用一些对象或者你想释放一些内存,可以传递false这个值来卸载已经压缩好了的文件从你的内存中(即.unity3d文件)。如果要完全卸载所有的资源数据,需要传递true这个值,这将会销毁所有的资源包器中加载的资源。

Listing objects in an AssetBundle 从资源包列表物体

You can use AssetBundle.LoadAll to retrieve an array containing all objects from the AssetBundle. It is not possible to get a list of the identifiers directly. A common workaround is to keep a separate TextAsset with a known name to hold the names of the assets in the AssetBundle.

可以使用AssetBundle.LoadAll 去取回资源包中包含的所有对象的数组。不可能直接就取回一个列表。通常的做法是保持一个单独的TextAsset,这个TextAsset是控制资源包中资源的名称。

Instantiating objects from AssetBundles 从资源包实例化物体

Once you have loaded an object from your AssetBundle, you can instantiate it in your scene with theInstantiate function.

下载了资源,也加载好了,那么就该在场景中使用Instantiate函数去实例化它了。

string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
    // Start a download of the given URL
	// 开始从指定路径下载
    WWW www = WWW.LoadFromCacheOrDownload (url, 1);

    // Wait for download to complete
	// 等待下载完成
    yield return www;

    // Load and retrieve the AssetBundle
	// 加载并取回资源包
    AssetBundle bundle = www.assetBundle;

    // Load the TextAsset object
	// 加载文本资源对象
    GameObject go = bundle.Load("myGameObject", typeof(GameObject)) as GameObject;

    // Instantiate the GameObject
	// 实例化该对象
    Instantiate(go);
}

Keeping track of downloaded AssetBundles 保持跟踪下载的资源包

Unity doesn't provide an automatic way to retrieve a list of AssetBundles that have been downloaded. You can keep track of this information from a script by storing references to the AssetBundle objects and their URLs, say.

Unity不提供自动的一个可以取回所有被下载资源的列表。所以需要我们在脚本中要建立这些资源对象的信息和它们的路径以便我们去查找。

Storing and loading binary data in an AssetBundle 在资源包储存和加载二进制数据

The first step is to save your binary data file with the ".bytes" extension. Unity will treat this file as aTextAsset. As a TextAsset the file can be included when you build your AssetBundle. Once you have downloaded the AssetBundle in your application and loaded the TextAsset object, you can use the .bytes property of the TextAsset to retrieve your binary data.

第一步要储存文件的扩展名以" .bytes"为结尾的二进制数据。Unity会把它们看成TextAsset来使用。当你建立资源包就会包含一个TestAsset的文件。当在资源包应用程序中下载好这个二进制数据后也需要加载它们,可以使用TextAsset的.bytes的属性去取回你的二进制数据。

string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
    // Start a download of the given URL
    WWW www = WWW.LoadFromCacheOrDownload (url, 1);

    // Wait for download to complete
    yield return www;

    // Load and retrieve the AssetBundle
    AssetBundle bundle = www.assetBundle;

    // Load the TextAsset object
    TextAsset txt = bundle.Load("myBinaryAsText", typeof(TextAsset)) as TextAsset;

    // Retrieve the binary data as an array of bytes
    byte[] bytes = txt.bytes;
}

Including scripts in AssetBundles 在资源包中包含脚本

AssetBundles can contain scripts as TextAssets but as such they will not be actual executable code. If you want to include code in your AssetBundles that can be executed in your application it needs to be pre-compiled into an assembly and loaded using the Mono Reflection class (Note: Reflection is not available on iOS). You can create your assemblies in any normal C# IDE (e.g. Monodevelop, Visual Studio) or any text editor using the mono/.net compilers.

资源包可以作为TextAssets包含脚本但是不会实际执行代码。如果想要在资源包包含用来执行应用程序的代码,需要预先编译,然后使用Mono Reflection class来加载(注意:Reflection在iOS平台不可用)。可以在任何版本的C#IDE编辑器(如:Monodevelop, Visual Studio)或者使用mono/.net 文档编辑器。

string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
    // Start a download of the given URL
    WWW www = WWW.LoadFromCacheOrDownload (url, 1);

    // Wait for download to complete
    yield return www;

    // Load and retrieve the AssetBundle
    AssetBundle bundle = www.assetBundle;

    // Load the TextAsset object
    TextAsset txt = bundle.Load("myBinaryAsText", typeof(TextAsset)) as TextAsset;

    // Load the assembly and get a type (class) from it
    var assembly = System.Reflection.Assembly.Load(txt.bytes);
    var type = assembly.GetType("MyClassDerivedFromMonoBehaviour");

    // Instantiate a GameObject and add a component with the loaded class
    GameObject go = new GameObject();
    go.AddComponent(type);
}

Managing asset dependencies 管理相关资源

Any given asset in a bundle may depend on other assets. For example, a model may incorporate materials which in turn make use of textures and shaders. It is possible to include all an asset's dependencies along with it in its bundle. However, several assets from different bundles may all depend on a common set of other assets (eg, several different models of buildings may use the same brick texture). If a separate copy of a shared dependency is included in each bundle that has objects using it, then redundant instances of the assets will be created when the bundles are loaded. This will result in wasted memory.

任何在资源包中给出的资源可能主要依赖于其它的资源。举个例子,一个模型可能混合多种纹理和材质球中的材质,可能包括所有的某个资源相关的东西,然而,一些从不同资源包文件夹中的资源或许都要用到相同的一些其它资源(比如说一些不同的建筑模型会用到相同的纹理贴图)。如果在每个资源文件夹中包含一个被共享的资源要被某个对象用到,当资源文件加载的时候那就不需要去实例化多余的对象,换句话说就是只要把共享的资源实例化一次就可以了,这样就可以大大减少内存的占用。

To avoid such wastage, it is possible to separate shared dependencies out into a separate bundle and simply reference them from any bundles with assets that need them. First, the referencing feature needs to be enabled with a call toBuildPipeline.PushAssetDependencies. Then, the bundle containing the referenced dependencies needs to be built. Next, another call to PushAssetDependencies should be made before building the bundles that reference the assets from the first bundle. Additional levels of dependency can be introduced using further calls to PushAssetDependencies. The levels of reference are stored on a stack, so it is possible to go back a level using the correspondingBuildPipeline.PopAssetDependencies function. The push and pop calls need to be balanced including the initial push that happens before building.

要避免资源的浪费,可以单独建立一个专门的文件夹用来放要被共享的资源或者所有需要被加载的对象,官方提供的AssetBundles Example Project中的AssetBundles这个文件夹就是一个不错的选择,要查看该文件夹需要进入unity3D->在Project中右击会看到一个下拉菜单有Auto Build Rescources Files的选项,点击它,然后进入AsssetBundles资源目录下你会发现多了一个名为AssetBundles的文件夹,所有的资源已经被转化成.unity3d的格式存储在这里了。要把这些资源存储在指定的AssetBundles这个文件夹下,需要用到BuildPipeline.PushAssetDependencies和BuildPipeline.PopAssetDependencies这两个函数。首先需要BuildPipeline.PushAssetDependencies来激活将要使用到的资源文件夹(比如AssetBundles Example Project中的AssetBundles这个文件夹)。然后就需要建立你想在这个文件夹中存放什么资源了,比如说一个纹理贴图。接着再次呼叫BuildPipeline.PushAssetDependencies来激活下一个将要使用到的和先前存放资源相关的其它资源。比如说有一个角色的模型,这个角色模型有它自己的纹理贴图,那就需要先激活它的贴图然后激活模型本身。如此反复直到把所有与需要加载资源的其它相关资源都使用BuildPipeline.PushAssetDependencies加载完毕,最后再使用BuildPipeline.PopAssetDependencies来告诉程序这个模型所有的相关资源已经全部加载完成。

At runtime, you need to load a bundle containing dependencies before any other bundle that references them. For example, you would need to load a bundle of shared textures before loading a separate bundle of materials that reference those textures.

在运行时,需要考虑到优先加载资源的顺序。举个例子,现在有一张纹理贴图,这张贴图可能被很多个模型需要用到,而这个贴图又有很多不同的材质,那就得先加载纹理贴图,然后材质,最后才是模型。

具体的代码实现过程可参考AssetBundles Example Project中的AutoExportRescources这个脚本。

Can I reuse my AssetBundles in another game?
可以在其他的游戏场景重新使用我的资源包吗?

AssetBundles allow you to share content between different games. The requirement is that any Assets which are referenced by GameObjects in your AssetBundle must either be included in the AssetBundle or exist in the application (loaded in the current scene). To make sure the referenced Assets are included in the AssetBundle when they are built you can pass theBuildAssetBundleOptions.CollectDependencies option.

资源包允许用户去共享资源包中的内容到其它不同的游戏。如果需要共享,前提需要你已经建立好这个资源包共享文件。可以使用BuildAssetBundleOptions.CollectDependencies这个函数来检测是否已经建立好资源包文件。

How are assets in AssetBundles identified?
资源包中的资源如何被识别?

When you build AssetBundles the assets are identified internally by their filename without the extension. For example a Texture located in your Project folder at "Assets/Textures/myTexture.jpg" is identified and loaded using "myTexture" if you use the default method. You can have more control over this by supplying your own array of ids (strings) for each object when Building your AssetBundle withBuildPipeline.BuildAssetBundleExplicitAssetNames.

当在内部建立资源包时,它们的文件名不包含扩展名就会被识别。举个例子,一个在你项目工程目录下比如说"Assets/Textures/myTextures.jpg"的贴图是用"myTexture"来识别。如果使用默认的方法,当你用BuildPipeline.BuildAssetBundleExplicitAssetNames这个函数建立你的资源包,那你可以有很多你自己编号的数组上的控制。

Loading objects from an AssetBundles asynchronously
从资源包异步加载对象

You can use the AssetBundle.LoadAsync method to load objects Asynchronously and reduce the likelihood of having hiccups in your application.

可以使用AssetBundle.LoadAsync方法来异步加载对象,这样一来可以减少在应用程序中被打断的可能性。

using UnityEngine;

IEnumerator Start () {
	// Start a download of the given URL
	WWW www = WWW.LoadFromCacheOrDownload (url, 1);

	// Wait for download to complete
	yield return www;

	// Load and retrieve the AssetBundle
	AssetBundle bundle = www.assetBundle;

	// Load the object asynchronously
	AssetBundleRequest request = bundle.LoadAsync ("myObject", typeof(GameObject));

	// Wait for completion
	yield return request;

	// Get the reference to the loaded object
	GameObject obj = request.asset as GameObject;
}

Are AssetBundles cross-platform?
资源包可以跨平台吗?

AssetBundles are compatible between some platforms. Use the following table as a guideline.

在有一些平台中是可以兼容的,可以参考下面的这个表格。

Platform compatibility for AssetBundles 资源包在平台的兼容性
 StandaloneWebplayeriOSAndroid
EditorYYYY
StandaloneYY  
WebplayerYY  
iOS  Y 
Android   Y

How do I cache AssetBundles? 如何缓存资源包?

You can use WWW.LoadFromCacheOrDownload which automatically takes care of saving your AssetBundles to disk. Be aware that on the Webplayer you are limited to 50MB in total (shared between all webplayers). You can buy a separate caching license for your game if you require more space.

使用WWW.LoadFromCacheOrDownload就可以自动在你的硬盘上存储资源包文件。但是说明一下Webplayer被限制50MB的存储空间。如果需要更多空间则可以单独为游戏购买缓存许可证。

Protecting content 保护内容

Unity allows you to create an AssetBundle object from a byte[] array with AssetBundle.CreateFromMemory. You can use this as a way to enhance the security by encrypting your assetbundles before transmission and decrypt them at runtime.

Unity允许用户使用AssetBundle.CreateFromMemory从一个 byte[]数组中建立一个AssetBundle的对象。在运行时传输和解密之前,可以用这种加密方法来提高安全性和保护用户建立的资源包中内容。

string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
    // Start a download of the given URL
    WWW www = new WWW (url);

    // Wait for download to complete
    yield return www;

    // Get the byte data
    byte[] encryptedData = www.bytes;

    // Load the TextAsset object
    byte[] decryptedData = YourDecryptionMethod(encryptedData);

    // Create an AssetBundle from the bytes array
    AssetBundle bundle = AssetBundle.CreateFromMemory(decryptedData);

    // You can now use your AssetBundle
}

页面最后更新: 2011-06-21

分类: Manual| 翻译: huzi1986216

 

 

圣典原址:http://game.ceeger.com/Manual/AssetBundles.html

 

 

 

 

 

 

 

 

 

BuildPipeline.BuildStreamedSceneAssetBundle 编译流场景资源包

static function BuildStreamedSceneAssetBundle (levels : string[],locationPath :String,target :BuildTarget) :String

Description描述

Builds one or more scenes and all it's dependencies into a compressed asset bundle.

编译一个或多个场景和所有它依赖的压缩资源包。

The scene AssetBundle can be built for any target platform and always creates a single compressed unity3d file.

该场景资源包可以内置任意目标平台,并总是创建单一压缩的unity3d文件。

The scene can be downloaded and loaded using the WWW class. You can use WWW.LoadFromCacheOrDownload to cache the downloaded scene after it has been downloaded.

该场景可以被下载并使用WWW类加载。可以使用WWW.LoadFromCacheOrDownload已经被下载后,来缓存下载的场景。

// Build a streamed unity3d file. This contain one scene that can be downloaded
// on demand and loaded once it's asset bundle has been loaded.
//构建一个流unity3d文件,包含一个场景,可以按需下载,一旦资源包加载时加载。

@MenuItem ("Build/BuildWebplayerStreamed")
static function MyBuild(){
	var levels : String[] = ["Assets/Level1.unity"];
	BuildPipeline.BuildStreamedSceneAssetBundle( levels, "Streamed-Level1.unity3d", BuildTarget.WebPlayer);
}

When downloading the built compressed file, you need to call WWW.assetBundle in order to make the scene available to the Application.LoadLevel() and Application.LoadLevelAdditive() functions.

当下载内置的压缩文件,必须调用WWW.assetBundle以使场景Application.LoadLevel()和Application.LoadLevelAdditive()函数可用。

function Start () {
	// Download compressed scene. If version 5 of the file named "Streamed-Level1.unity3d" was previously downloaded and cached.
	// Then Unity will completely skip the download and load the decompressed scene directly from disk.
	//下载压缩的场景。如果名为Streamed-Level1.unity3d的文件版本为5,预先下载并缓存。
	//然后Unity将完全跳过下载并直接从磁盘加载解压的场景。
	var download = WWW.LoadFromCacheOrDownload ("http://myWebSite.com/Streamed-Level1.unity3d", 5);
	yield download;

	// Handle error
	if (download.error != null)
	{
		Debug.LogError(download.error);
		return;
	}

	// In order to make the scene available from LoadLevel, we have to load the asset bundle.
	// The AssetBundle class also lets you force unload all assets and file storage once it is no longer needed.
	//为了使场景LoadLevel可用,必须加载资源包
	//AssetBundle类,还可以强制卸载所有的资源和文件存储,一旦不再需要。
	var bundle = download.assetBundle;

	// Load the level we have just downloaded
	//加载刚才下载的关卡
	Application.LoadLevel ("Level1");
}
最后修改:2011年10月3日 Monday 14:42

 

 

 

 

圣典原址:http://game.ceeger.com/Script/BuildPipeline/BuildPipeline.BuildStreamedSceneAssetBundle.html

 

 

 

 

 

 

BuildPipeline.BuildAssetBundleExplicitAssetNames 编译资源包带有资源名

static function BuildAssetBundleExplicitAssetNames (assets :Object[],assetNames : string[],pathName : string,options :BuildAssetBundleOptions = BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets, targetPlatform : BuildTarget = BuildTarget.WebPlayer) : bool

Description描述

Builds an asset bundle, with custom names for the assets (Unity Pro only).

生成一个资源包,带有资源的自定义名称(仅用于Unity Pro)。

Creates a compressed unity3d file that contains a collection of assets. AssetBundles can contain any asset found in the project folder. In the assetNames parameter, supply an array of strings of the same size as the number of assets. These will be used as asset names, which you can then pass to AssetBundle.Load to load a specific asset. Use BuildAssetBundle to just use the asset's path names instead. The compressed asset bundle file will be saved at pathName. options allows you to automatically include dependencies or always include complete assets instead of just the exact referenced objects.

创建一个压缩的unity3d文件,包含资源的集合。资源包可以包含任何项目文件中的资源。在assetNames参数,然后可以传递给AssetBundle.Load加载一个特定的资源。使用BuildAssetBundle只使用资源的路径名替代。压缩的资源包文件将保持在pathName。options允许您自动包括依赖关系或总是包含完整的资源,而不只是准确引用的对象。

参见:BuildAssetBundle,AssetBundle 类,WWW.assetBundle.

// C# Example
// Builds an asset bundle from the selected folder in the project view.
// Bare in mind that this script doesnt track dependencies nor is recursive
//在项目视图从选择的文件夹生成资源包
//记住,这个脚本不跟踪依赖关系,也不是递归
using UnityEngine;
using UnityEditor;
using System.IO;

public class BuildAssetBundlesFromDirectory {
	[@MenuItem("Asset/Build AssetBundles From Directory of Files")]
	static void ExportAssetBundles () {
		// Get the selected directory
		//获取选择的目录
		string path = AssetDatabase.GetAssetPath(Selection.activeObject);
		Debug.Log("Selected Folder: " + path);
		if (path.Length != 0) {
			path = path.Replace("Assets/", "");
			string [] fileEntries = Directory.GetFiles(Application.dataPath+"/"+path);
			foreach(string fileName in fileEntries) {
				string filePath = fileName.Replace("", "/");
				int index = filePath.LastIndexOf("/");
				filePath = filePath.Substring(index);
				Debug.Log(filePath);
				string localPath = "Assets/" + path;
				if (index > 0)
				localPath += filePath;
				Object t = AssetDatabase.LoadMainAssetAtPath(localPath);
				if (t != null) {
					Debug.Log(t.name);
					string bundlePath = "Assets/" + path + "/" + t.name + ".unity3d";
					Debug.Log("Building bundle at: " + bundlePath);
					// Build the resource file from the active selection.
					//从激活的选择编译资源文件
					BuildPipeline.BuildAssetBundle
					(t, null, bundlePath, BuildAssetBundleOptions.CompleteAssets);
				}

			}
		}
	}
}
最后修改:2011年5月8日 Sunday 9:44

 

 

 

圣典原址:http://game.ceeger.com/Script/BuildPipeline/BuildPipeline.BuildAssetBundleExplicitAssetNames.html

 

 

 

 

 

BuildPipeline.BuildAssetBundle 编译资源包

static function BuildAssetBundle (mainAsset : Object, assets : Object[], pathName : string, options : BuildAssetBundleOptions = BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets, targetPlatform : BuildTarget = BuildTarget.WebPlayer) : bool

Description描述

Builds an asset bundle (Unity Pro only).

生成一个资源包(仅用于Unity Pro)。

Creates a compressed unity3d file that contains a collection of assets. AssetBundles can contain any asset found in the project folder. This lets you stream resource data of any type, fully setup prefabs, textures, meshes, animations, any type of asset shown in the project window. mainAsset lets you specify a specific object that can be conveniently retrieved usingAssetBundle.mainAsset. The compressed asset bundle file will be saved at pathName. options allows you to automatically include dependencies or always include complete assets instead of just the exact referenced objects. All paths are relative to the project folder. Like: "Assets/MyTextures/hello.png"

创建一个压缩的unity3d文件,包含资源的集合。资源包可以包含任何项目文件中的资源。这可以让你流任何类型的资源数据,全部的预置设置,纹理,网格,动画等显示在项目窗口中的任意类型。mainAsset让你指定一个特定对象,可以方便的使用AssetBundle.mainAsset检索。压缩的资源包文件将保持在pathName。options允许您自动包括依赖关系或总是包含完整的资源,而不只是准确引用的对象。所有路径相对于项目文件夹。像: "Assets/MyTextures/hello.png"

参见: AssetBundle 类,WWW.assetBundle.

// C# Example
// Builds an asset bundle from the selected folder in the project view.
// Bare in mind that this script doesnt track dependencies nor is recursive
//在项目视图从选择的文件夹生成资源包
//记住,这个脚本不跟踪依赖关系,也不是递归
using UnityEngine;
using UnityEditor;
using System.IO;

public class BuildAssetBundlesFromDirectory {
	[@MenuItem("Asset/Build AssetBundles From Directory of Files")]
	static void ExportAssetBundles () {
		// Get the selected directory
		//获取选择的目录
		string path = AssetDatabase.GetAssetPath(Selection.activeObject);
		Debug.Log("Selected Folder: " + path);
		if (path.Length != 0) {
			path = path.Replace("Assets/", "");
			string [] fileEntries = Directory.GetFiles(Application.dataPath+"/"+path);
			foreach(string fileName in fileEntries) {
				string filePath = fileName.Replace("", "/");
				int index = filePath.LastIndexOf("/");
				filePath = filePath.Substring(index);
				Debug.Log(filePath);
				string localPath = "Assets/" + path;
				if (index > 0)
				localPath += filePath;
				Object t = AssetDatabase.LoadMainAssetAtPath(localPath);
				if (t != null) {
					Debug.Log(t.name);
					string bundlePath = "Assets/" + path + "/" + t.name + ".unity3d";
					Debug.Log("Building bundle at: " + bundlePath);
					// Build the resource file from the active selection.
					//从激活的选择编译资源文件
					BuildPipeline.BuildAssetBundle
					(t, null, bundlePath, BuildAssetBundleOptions.CompleteAssets);
				}

			}
		}
	}
}
最后修改:2011年5月8日 Sunday 9:30

 

 

圣典原址:http://game.ceeger.com/Script/BuildPipeline/BuildPipeline.BuildAssetBundle.html

 

 

 

請問Asset bundle使用方式

 

 

 不好意思 我是剛入門unity的新手 想請問大家有關asset bundle使用上的問題

今天想實作一個Asset bundle的範例
想把Aseet中的資源(animation,texure...等) 製作成Asset bundle
已經可以產生一個叫test123的Asset bundle 把上面資源包在一起
那請問我要如何將這test123 Asset bundle完整解開到程式中執行
有查到可以用WWW bundle = new WWW(path); 取得bundle
那接下來我要如何還原asset bundle內的資源呢??

使用語法如下

void buildBundle_Mj2()
{
    // AssetBundle 的資料夾名稱及副檔名
    string targetDir = "assetbundle";
    string extensionName = ".unity3d";
        
    // 檢查所選的資料夾
    //GameObject selected = Selection.activeGameObject;
        
    //取得在 Project 視窗中選擇的資源(包含資料夾的子目錄中的資源)
    Object[] SelectedAsset = Selection.GetFiltered(typeof (Object), SelectionMode.DeepAssets);
        
    //建立存放 AssetBundle 的主資料夾資料夾
    if(!Directory.Exists(targetDir)) Directory.CreateDirectory(targetDir);
        
    // 全塞到同一個目錄
    string targetPath = targetDir + "/_ab/test123" + extensionName;    
        
    if (targetPath.Length != 0) {
        // Build the resource file from the active selection.
        Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
        BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, targetPath, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets);
        Selection.objects = selection;
        }
}

 

 

 

 using System;
using UnityEngine;
using System.Collections; class NonCachingLoadExample : MonoBehaviour {
   public string BundleURL;
   public string AssetName;
   IEnumerator Start() {
       // Download the file from the URL. It will not be saved in the Cache
       using (WWW www = new WWW(BundleURL)) {
           yield return www;
           if (www.error != null)
               throw new Exception("WWW download had an error:" + www.error);
           AssetBundle bundle = www.assetBundle;
           if (AssetName == "")
               Instantiate(bundle.mainAsset);
           else
               Instantiate(bundle.Load(AssetName));
                   // Unload the AssetBundles compressed contents to conserve memory
                   bundle.Unload(false);
       }
   }
}

官方脚本,上面的是下载资源包。下面的是使用资源包
using UnityEngine;
// Note: This example does not check for errors. Please look at the example in the DownloadingAssetBundles section for more informationIEnumerator Start () {
// Start a download of the given URL
WWW www = www.LoadFromCacheOrDownload (url, 1);
// Wait for download to complete
yield return www;
// Load and retrieve the AssetBundle
AssetBundle bundle = www.assetBundle;
// Load the object asynchronously
AssetBundleRequest request = bundle.LoadAsync ("myObject", typeof(GameObject));
// Wait for completion
yield return request;
// Get the reference to the loaded object
GameObject obj = request.asset as GameObject;
// Unload the AssetBundles compressed contents to conserve memory
bundle.Unload(false);
}

 

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AssetBundle是 Unity 引擎中的一项功能,它可以将游戏资源(如模型、贴图、声音等)打成一个可供Unity项目使用的二进制文件。 在Unity中,资源一般存储在项目中的Assets文件夹下。AssetBundle可以将Assets文件夹下的相关资源成二进制文件,这样可以提高游戏加载效率和节约存储空间。使用AssetBundle后的资源可以在运行时动态加载,而无需把所有资源都放在游戏启动时一次性加载。 AssetBundle有两个主要步骤:构建AssetBundle和导入AssetBundle。 构建AssetBundle是将指定的资源成二进制文件的过程。在Unity编辑器中,可以通过选择要打资源并设置相关的打属性,然后点击菜单中的Build选项来执行构建。AssetBundle的构建可以针对不同的平台进行,比如PC、移动设备、Web等,以便在不同平台上使用相应的AssetBundle。 导入AssetBundle是将打好的二进制文件导入到Unity项目中的过程。导入AssetBundle时,可以通过提供AssetBundle的路径或URL来加载资源,然后通过代码将资源实例化、加载到场景中或执行其他操作。 使用AssetBundle可以优化游戏的性能和加载速度,特别是对于大型游戏项目或需要频繁更新资源的项目来说。通过打资源成AssetBundle,可以实现资源的动态加载,提高游戏的流畅性和用户体验。 需要注意的是,在使用AssetBundle资源时,要注意打资源的依赖关系,确保打资源能够正确加载和使用,并且需要注意资源的版本控制,以便在项目更新时能够正确地更新AssetBundle中的资源

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值