Unity3d之AssetBundle打包与读取
一、创建Assetbundle
在unity3d开发的游戏中,无论模型,音频,还是图片等,我们都做成Prefab,然后打包成Assetbundle,方便我们后面的使用,来达到资源的更新。
一个Assetbundle可以打包一个模型(这里的模型不单单指的是预制模型,可以是Project视图下的任何东西),也可以是多个模型,但两种打包方式占用的空间不一样。
比如我打包三个一样的模型(只不过他们的脚本不一样创建三个空的GameObject(One,Two,Three),分别挂载脚本One,Two,Three)。如果我为每个模型单独打包生成One,Two,Three三个Assetbundle,其所占的空间是A,B,C,但是A+B+C != D.由此可知想通的资源尽可能的打包到一起,他们共用一套资源。不相同的模型尽量分开打包。
二、分开打包(注意这个脚本必须放在Editor文件夹内,Editor文件夹没有的话需自己创建)
/// <summary> /// 将选中的预制分别打包 /// </summary> [MenuItem("AssetBundleDemo/Create AssetBundles By themselves")] static void CreateAssetBundleThemelves(){ //获取要打包的对象(在Project视图中) Object[] selects = Selection.GetFiltered (typeof(Object),SelectionMode.DeepAssets); //遍历选中的对象 foreach(Object obj in selects){ //这里建立一个本地测试 //注意本地测试中可以是任意的文件,但是到了移动平台只能读取路径StreamingAssets里面的 //StreamingAssets是只读路径,不能写入 string targetPath = Application.dataPath + "/AssetBundleLearn/StreamingAssets/" + obj.name + ".assetbundle";//文件的后缀名是assetbundle和unity都可以 if(BuildPipeline.BuildAssetBundle(obj,null,targetPath,BuildAssetBundleOptions.CollectDependencies)){ Debug.Log(obj.name + "is packed successfully!"); }else{ Debug.Log(obj.name + "is packed failly!"); } } //刷新编辑器(不写的话要手动刷新,否则打包的资源不能及时在Project视图内显示) AssetDatabase.Refresh (); }
SelectionMode.DeepAssets
这个选择模式意味着如果选择中包含多个文件,那么他将包含这个文件视图中的所有资源。
他还有其他的各种选项(以下是官方文档)
SelectionMode can be used to tweak the selection returned by Selection.GetTransforms.
The default transform selection mode is: SelectionMode.TopLevel | SelectionMode.ExcludePrefab | SelectionMode.Editable.
Unfiltered | Return the whole selection. |
TopLevel | Only return the topmost selected transform. A selected child of another selected transform will be filtered out. |
Deep | Return the selection and all child transforms of the selection. |
ExcludePrefab | Excludes any prefabs from the selection. |
Editable | Excludes any objects which shall not be modified. |
Assets | Only return objects that are assets in the Asset directory. |
DeepAssets | If the selection contains folders, also include all assets and subfolders within that folder in the file hierarchy. |
最核心的方法:BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)
参数1:它只能放一个对象,因为我们这里是分别打包,所以通过循环将每个对象分别放在了这里。
参数2:可以放入一个数组对象。
参数3:要打包到的路径
参数4:默认情况下打的包只能在电脑上用,如果要在手机上用就要添加一个参数。
Android上:
BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies,BuildTarget.Android)
IOS上:
BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies,BuildTarget.iPhone)
另外,电脑上和手机上打出来的Assetbundle不能混用,不同平台只能用自己的。
三、一起打包/// <summary> /// 将选中的预制打包到一起 /// </summary> [MenuItem("AssetBundleDemo/Create AssetBundles Together")] static void CreateAssetBundleTogether(){ //要打包的对象 Object[] selects = Selection.GetFiltered (typeof(Object),SelectionMode.DeepAssets); //要打包到的路径 string targetPath = Application.dataPath + "/AssetBundleLearn/StreamingAssets/Together.assetbundle"; if(BuildPipeline.BuildAssetBundle(null,selects,targetPath,BuildAssetBundleOptions.CollectDependencies)){ Debug.Log("Packed successfully!"); }else{ Debug.Log("Packed failly!"); } //刷新编辑器(不写的话要手动刷新) AssetDatabase.Refresh (); } }
四、读取
using UnityEngine; using System.Collections; public class ReanAssetbundle : MonoBehaviour { //不同平台下StreamingAssets的路径是不同的,这里需要注意一下。 public static readonly string m_PathURL = #if UNITY_ANDROID "jar:file://" + Application.dataPath + "!/assets/"; #elif UNITY_IPHONE Application.dataPath + "/Raw/"; #elif UNITY_STANDALONE_WIN || UNITY_EDITOR "file://" + Application.dataPath + "/AssetBundleLearn/StreamingAssets/"; #else string.Empty; #endif void OnGUI(){ if(GUILayout.Button("加载分开打包的Assetbundle")){ StartCoroutine(LoadGameObjectPackedByThemselves(m_PathURL + "One.assetbundle")); StartCoroutine(LoadGameObjectPackedByThemselves(m_PathURL + "Two.assetbundle")); StartCoroutine(LoadGameObjectPackedByThemselves(m_PathURL + "Three.assetbundle")); } if(GUILayout.Button("加载打包在一起的Assetbundle")){ StartCoroutine(LoadGameObjectPackedTogether(m_PathURL + "Together.assetbundle")); } } //单独读取资源 private IEnumerator LoadGameObjectPackedByThemselves(string path){ WWW bundle = new WWW (path); yield return bundle; //加载 yield return Instantiate (bundle.assetBundle.mainAsset); bundle.assetBundle.Unload (false); } IEnumerator LoadGameObjectPackedTogether (string path) { WWW bundle = new WWW (path); yield return bundle; Object one = bundle.assetBundle.Load ("One"); Object two = bundle.assetBundle.Load ("Two"); Object three = bundle.assetBundle.Load ("Three"); //加载 yield return Instantiate (one); yield return Instantiate (two); yield return Instantiate (three); bundle.assetBundle.Unload (false); } }
- 上一篇: yii crontab 命令使用 经测试
- 下一篇: 高可用性、负载均衡的mysql集群解决方案