[MenuItem("Tools/AssetsBoundle/SelectBundle")]
//MenuItem是在unity的工具栏中建立一个新的菜单栏Tools->AssetBundle->SelectBundle
public static void SelectBundle(){
//创建一个字典用于存储AssetBundleBulid对象,以对象的assetBundleName和assetBundleVariant拼接成字符串作为key
Dictionary<string,AssetBundleBuild> assets = new Dictionary<string, AssetBundleBuild> ();
/*获取所有的鼠标选择的对象,Selection是对鼠标选择做出的一些操作,GetFiltered是对鼠标选择的对象做出筛选,第一个参数是筛选的类型,第二个参数是筛选的模式,当前是选择了鼠标选中的所有文件夹里面的所有对象*/
Object[] objList = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets);
//Debug.Log(objList.Length);
//下面的for循环是在将选中的对象添加到字典中
for (var i = 0; i < objList.Length; i++) {
//Debug.Log (objList[i]);
/*获取该对象的在资源文件夹中的相对路径//AssetDatabase是一个对asset进行访问和操作的密封类,可以通过这个类获得对象的路径*/
string path=AssetDatabase.GetAssetPath(objList[i]);
Debug.Log (path);
//通过路径返回资源设置好的资源包的名字
string assetName = AssetImporter.GetAtPath (path).assetBundleName;
//返回该对象的assetBundleVariant;
string variant= AssetImporter.GetAtPath (path).assetBundleVariant;
string key = assetName + "." + variant;
//Debug.Log (key);
if (assets.ContainsKey (key)) {
//原基础更新
/*如果该资源包名字和Variant存在则创建一个AssetBundleBulid对象bulid来存储该资源包内的AssetBundleBulid对象,bulid有三个属性assetNames是一个字符串数组用于存储需要打包的对象的路径,这里赋值添加一个路径之后又重新赋值给该键的键值*/
AssetBundleBuild build=assets[key];
build.assetNames = AppendChild (build.assetNames, path);
assets [key] = build;
}else{
/*这里是在判断在字典中没有找到该key,但是key不为null也不是空字符串则新建一个bulid并给bulid的三个属性赋值*/
if (key != null && key != ""&&key.Length>1) {
Debug.Log ("456");
AssetBundleBuild build = new AssetBundleBuild ();
build.assetBundleName = assetName;
build.assetBundleVariant = variant;
build.assetNames = new string[]{ path };
assets.Add (key, build);
} else {
/*用于打包那些没有包名的对象这时候key=".",所以将这些没有包名的对象以它们的类型进行打包*/
key = path.Substring (path.LastIndexOf (".") + 1);
Debug.Log (key);
if (assets.ContainsKey (key)) {
//原基础更新
/*如果已经创建了该key则添加一个路径*/
AssetBundleBuild build=assets[key];
build.assetNames = AppendChild (build.assetNames, path);
assets [key] = build;
}else{
/*如果不存在则新建一个键值对*/
AssetBundleBuild build = new AssetBundleBuild ();
build.assetBundleName = key;
build.assetNames = new string[]{ path };
assets.Add (key, build);
}
}
}
}
Debug.Log ("123");
//启动打包
AssetBundleBuild[] crr=new AssetBundleBuild[assets.Count];
assets.Values.CopyTo (crr,0);
Debug.Log (crr[0].assetBundleName);
//这里进行打包
BuildPipeline.BuildAssetBundles(Application.dataPath+"/AssetsBundle",crr,BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows64);
}
static string[] AppendChild(string[] arr,string value){
string[] brr = new string[arr.Length + 1];
for (var i = 0; i < arr.Length; i++) {
brr [i] = arr [i];
}
brr [brr.Length - 1] = value;
return brr;
}
}
总体思路:获取选择到的所有对象-->循环获取单个对象-->获取并拼接对象的资源包名和Variant作为键值-->判断键值是否存在-->(存在)将对象的地址存储到值中-->(不存在)创建新的键存储-->(没有资源包名和Variant)以该对象的类型作为键存储-->所有对象存储完毕后用BulidPipeline.BulidAssetBundle进行打包-->完成