Unity5.3更新了assetbundle的打包和加载api,下面简单介绍使用方法及示例代码。
在Unity中选中一个prefab查看Inspector窗口,有两个位置可以进行assetbundle的标记。
第一个为assetBundleName,如果这里不是None,则这个资源会记录到AssetDatabase里,使用BuildAssetBundles打包时,会自动将AssetBundleName一致的资源打到一个包中。
第二个为Variant,可用于区分不同分辨率的资源。如果在abName=S的情况下,variant有None也有HD,打ab包时会报错,如果variant有指定,则同一abName的资源的variant不能为None。
// 此api用于打包所有标记了AssetBundleName的资源
public static AssetBundleManifest BuildAssetBundles(
string outputPath,
BuildAssetBundleOptions assetBundleOptions = BuildAssetBundleOptions.None,
BuildTarget targetPlatform = BuildTarget.WebPlayer
);
// 此api用于打包指定的资源
public static AssetBundleManifest BuildAssetBundles(
string outputPath,
AssetBundleBuild[] builds,
BuildAssetBundleOptions assetBundleOptions = BuildAssetBundleOptions.None,
BuildTarget targetPlatform = BuildTarget.WebPlayer
);
其中,AssetBundleBuild数组参数,用于指定资源,AssetBundleBuild有三个属性,分别指定assetBundleName,variant,资源路径等。
以下为打包及加载部分代码:大部分参考了雨凇MOMO的文章《UGUI研究院之全面理解图集与使用(三)》,做了部分修改。
1 #define USE_ASSETBUNDLE 2 3 using UnityEngine; 4 using System.Collections; 5 using UnityEngine.UI; 6 using UnityEditor.VersionControl; 7 8 public class UIMain : MonoBehaviour{ 9 10 AssetBundle assetbundle = null; 11 void Start () 12 { 13 CreatImage(loadSprite("flag_blue")); 14 CreatImage(loadSprite("flag_yellow")); 15 } 16 17 private void CreatImage(GameObject gobj ){ 18 Sprite sprite = gobj.GetComponent<SpriteRenderer>().sprite as Sprite; 19 GameObject go = new GameObject(sprite.name); 20 go.layer = LayerMask.NameToLayer("UI"); 21 go.transform.parent = transform; 22 go.transform.localScale= Vector3.one; 23 Image image = go.AddComponent<Image>(); 24 image.sprite = sprite; 25 image.SetNativeSize(); 26 } 27 28 private GameObject loadSprite(string spriteName){ 29 #if USE_ASSETBUNDLE 30 if(assetbundle == null) 31 assetbundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath +"/flagbundle"); 32 return assetbundle.LoadAsset(spriteName) as GameObject; 33 #else 34 return Resources.Load<GameObject>("Sprite/" + spriteName); 35 #endif 36 } 37 38 }
1 using UnityEngine; 2 using System.Collections; 3 using System.Collections.Generic; 4 using UnityEditor; 5 using System.IO; 6 using UnityEditor.VersionControl; 7 8 public class AltasMaker : MonoBehaviour { 9 10 [MenuItem ("MyMenu/AtlasMaker")] 11 static private void MakeAtlas() 12 { 13 string spriteDir = Application.dataPath + "/Resources/Sprite"; 14 Debug.Log("spriteDir : " + spriteDir); 15 if(!Directory.Exists(spriteDir)){ 16 Directory.CreateDirectory(spriteDir); 17 } 18 19 DirectoryInfo rootDirInfo = new DirectoryInfo (Application.dataPath + "/Atlas"); 20 foreach (DirectoryInfo dirInfo in rootDirInfo.GetDirectories()) { 21 foreach (FileInfo pngFile in dirInfo.GetFiles("*.png", SearchOption.AllDirectories)) { 22 string allPath = pngFile.FullName; 23 Debug.Log("allPath1 : " + allPath); 24 string assetPath = allPath.Substring(allPath.IndexOf("Assets")); 25 Debug.Log("assetPath : " + assetPath); 26 Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(assetPath); 27 GameObject go = new GameObject(sprite.name); 28 go.AddComponent<SpriteRenderer>().sprite = sprite; 29 allPath = spriteDir+ "/" +sprite.name+ ".prefab"; 30 Debug.Log("allPath2 : " + allPath); 31 string prefabPath = allPath.Substring(allPath.IndexOf("Assets")); 32 PrefabUtility.CreatePrefab(prefabPath, go); 33 GameObject.DestroyImmediate(go); 34 } 35 } 36 } 37 38 [MenuItem ("MyMenu/Build Assetbundle")] 39 static private void BuildAssetBundle() 40 { 41 string outputdir = Application.dataPath + "/StreamingAssets"; 42 43 if(!Directory.Exists(outputdir)) 44 { 45 Directory.CreateDirectory(outputdir); 46 } 47 48 DirectoryInfo rootDirInfo = new DirectoryInfo (Application.dataPath + "/Atlas"); 49 foreach (DirectoryInfo dirInfo in rootDirInfo.GetDirectories()) { 50 List<Sprite> assets = new List<Sprite>(); 51 52 foreach (FileInfo pngFile in dirInfo.GetFiles("*.png", SearchOption.AllDirectories)) 53 { 54 string allPath = pngFile.FullName; 55 string assetPath = allPath.Substring(allPath.IndexOf("Assets")); 56 assets.Add(AssetDatabase.LoadAssetAtPath<Sprite>(assetPath)); 57 } 58 59 AssetBundleBuild[] buildMap = new AssetBundleBuild[1]; 60 61 buildMap[0].assetBundleName = dirInfo.Name + "bundle"; // 想定义的任何名称 62 string[] spriteNames = new string[assets.Count]; 63 for(int i = 0; i < assets.Count; i++) 64 { 65 spriteNames[i] = "Assets/Atlas/" + dirInfo.Name + "/" + assets[i].name + ".png"; // 注意路径写全 66 } 67 buildMap[0].assetNames = spriteNames; 68 buildMap[0].assetBundleVariant = null; 69 70 BuildPipeline.BuildAssetBundles( 71 outputdir, // output path 72 buildMap, // build bundles info 73 BuildAssetBundleOptions.UncompressedAssetBundle, // options 74 GetBuildTarget()); // build target 75 } 76 } 77 78 [MenuItem ("MyMenu/Build All AssetBundles")] 79 static private void BuildAllAssetBundles() 80 { 81 BuildPipeline.BuildAssetBundles( 82 Application.dataPath + "/StreamingAssets", // output path 83 BuildAssetBundleOptions.ChunkBasedCompression, // options 84 GetBuildTarget()); 85 } 86 87 static private BuildTarget GetBuildTarget() 88 { 89 BuildTarget target = BuildTarget.WebPlayer; 90 #if UNITY_STANDALONE 91 target = BuildTarget.StandaloneOSXIntel64; 92 #elif UNITY_IPHONE 93 target = BuildTarget.iPhone; 94 #elif UNITY_ANDROID 95 target = BuildTarget.Android; 96 #endif 97 return target; 98 } 99 }
注:1 经过验证,同一个资源如果没有改变,不会被重新build
2 如果缓存文件不刷新,强制调用Caching.CleanCache()。
assetbundle有三种压缩格式:默认为LZMA模式(最小),还有LZ4和不压缩(最大)。
不同压缩格式相关优缺点及使用详见下文:Unity5.x新的AssetBundle机制02——压缩
其他参考:
2 【厚积薄发】揭开Unity AssetBundle庐山真面目(二)