/// <summary> /// 压缩修改部分 /// </summary> public static void CompressDiff() { if (!File.Exists(GetOldHashPath())) { Debug.LogError("无法找到上次打包hash文件,无法差异压缩,已转为全部压缩"); CompressAll(); return; } //压缩差异资源 List <string> diffList = GetDiffHashList(GetOldHashPath(), GetNewHashPath()); string command = "a -tzip " + AssetBundleLoad.ZipName + " -aoa"; foreach (var item in diffList) { command += " "; //记得用引号啊,被坑了,有的美术资源带空格 command += ("\"" + item + "\""); } EditorTools.RunCommand("7z", command, AssetBundleLoad.GetAbParentPath()); //从压缩包中删除已经没有的文件 command = "d " + AssetBundleLoad.ZipName; List <string> deleteList = GetZipDeleteList(GetOldHashPath(), GetNewHashPath()); foreach (var item in deleteList) { command += " "; command += ("\"" + item + "\""); } EditorTools.RunCommand("7z", command, AssetBundleLoad.GetAbParentPath()); Debug.Log("差异压缩完成"); }
/// <summary> /// 全部压缩 /// </summary> public static void CompressAll() { string command = "a -tzip " + AssetBundleLoad.ZipName + " -aoa " + AssetBundleLoad.FolderName + "/" + AssetBundleLoad.FolderName + " " + AssetBundleLoad.FolderName + "/*.ab -r"; //EditorTools.RunCommand(@"D:\7z\7-Zip\7z.exe", command, AssetBundleLoad.GetAbParentPath(), true); EditorTools.RunCommand("7z", command, AssetBundleLoad.GetAbParentPath(), true); }
/// <summary> /// 比较hash文件,把差异单独压缩 /// </summary> public static void CompressForHotfix(bool isUpdateHash) { List <string> diffList = GetDiffHashList(isUpdateHash ? GetRemoteHashPath() : GetOldHashPath(), GetNewHashPath()); EditorTools.RunCommand("7z", @"d " + GetHotfixZipPath(), AssetBundleLoad.GetAbParentPath()); string command = @"a -tzip " + hotfixZipName; for (int i = 0; i < diffList.Count; i++) { command += " "; command += ("\"" + diffList[i] + "\""); } EditorTools.RunCommand("7z", command, AssetBundleLoad.GetAbParentPath()); Debug.Log("热更压缩完成"); }
public static void DeleteUnUsefulAssetBundle() { string manifestPath = AssetBundleLoad.GetAbPath() + AssetBundleLoad.FolderName; AssetBundle assetBundle = AssetBundle.LoadFromFile(manifestPath); AssetBundleManifest manifest = (AssetBundleManifest)assetBundle.LoadAsset("AssetBundleManifest", typeof(AssetBundleManifest)); string[] allAssetbundleNames = manifest.GetAllAssetBundles(); HashSet <string> set = new HashSet <string>(); for (int i = 0, count = allAssetbundleNames.Length; i < count; i++) { set.Add(allAssetbundleNames[i]); } assetBundle.Unload(false); DeleteAssetBundle(AssetBundleLoad.GetAbPath(), set); }
// 计算依赖数量长度 void CalculationDependencyCount(string assetBundleName, AssetBundleLoad load) { List <string> dependencys = load.GetDependencys(assetBundleName); if (dependencys == null) { return; } _totalCount += dependencys.Count; for (int i = 0; i < dependencys.Count; i++) { CalculationDependencyCount(dependencys[i], load); } }
IEnumerator LoadDependency(string assetBundleName, AssetBundleLoad load) { List <string> dependencys = load.GetDependencys(assetBundleName); if (dependencys == null) { yield break; } for (int i = 0; i < dependencys.Count; i++) { AssetBundleLoaderRequest request = AssetBundleLoaderRequest.New(dependencys[i]); load.LoadAssetBundleAsync(request); while (!request.IsDone) { yield return(null); } UpdateProgress(); } }
public void StartUnloadSceneAsync(AssetBundleLoad load) { if (!_uninstallable_scene.ContainsKey(_scene_name)) { return; } if (!_uninstallable_scene[_scene_name]) { return; } TextAsset xmlInfo = load.LoadAsset <TextAsset>(_xml_asset_bundle_name); Dictionary <XmlNode, XmlNodeList> sceneObjects = GetSceneObjects(xmlInfo); load.UninstallAssetBundle(_asset_bundle_name, true); if (sceneObjects != null) { var itr = sceneObjects.Keys.GetEnumerator(); while (itr.MoveNext()) // 遍历Object的节点 { XmlElement objectNode = itr.Current as XmlElement; string objectPath = objectNode.GetAttribute("Path"); string objectName = objectNode.GetAttribute("Name"); string assetBundleName = load.GetAssetBundleNameByAssetPath(objectPath); if (assetBundleName != string.Empty) { load.UninstallAssetBundle(assetBundleName, true); } } itr.Dispose(); } _uninstallable_scene.Remove(_scene_name); }
public static void BuildAssetBundle() { singlePathSet.Clear(); bundleDic.Clear(); //查找所有一级资源(以及需要被代码直接加载的资源) //这里建议所有需要单独加载的资源放在统一的文件夹内,要不容易落下 //这个模块没有放在外部,而写在代码里,主要是考虑很多路径是变量,放在外部不好管理 string[] strings = AssetDatabase.FindAssets("t:prefab t:scene t:AudioClip", new string[] { "Assets" }); for (int i = 0, count = strings.Length; i < count; i++) { singlePathSet.Add(AssetDatabase.GUIDToAssetPath(strings[i])); } //所有数据打包 strings = AssetDatabase.FindAssets("", new string[] { "Assets/Resources/Data" }); for (int i = 0, count = strings.Length; i < count; i++) { singlePathSet.Add(AssetDatabase.GUIDToAssetPath(strings[i])); } //反射资源路径类(因为在这个类里的一定都是需要单独加载的),遍历所有路径进行添加,由于set添加重复元素不会报错,所以这里不用处理 FieldInfo[] fieldInfos = typeof(ResPath).GetFields(); for (int i = 0; i < fieldInfos.Length; i++) { singlePathSet.Add(fieldInfos[i].GetValue(null).ToString()); } //在这里添加单独引用的资源 foreach (var item in singlePathSet) { bundleDic.Add(item, item); } foreach (var item in singlePathSet) { CheckDepends(item, item); } //转为打包格式 Dictionary <string, List <string> > dependsDic = new Dictionary <string, List <string> >(); foreach (var kv in bundleDic) { string singlePath = kv.Value; //场景特殊处理,场景不能和其他东西在一个Bundle里 if (singlePath.EndsWith(".unity")) { singlePath = kv.Key; } if (!dependsDic.ContainsKey(singlePath)) { dependsDic.Add(singlePath, new List <string>()); } dependsDic[singlePath].Add(kv.Key); } //最终打包List List <AssetBundleBuild> buildList = new List <AssetBundleBuild>(); foreach (var kv in dependsDic) { AssetBundleBuild build = new AssetBundleBuild(); build.assetBundleName = AssetBundleLoad.GetAbName(kv.Key); build.assetNames = kv.Value.ToArray(); buildList.Add(build); } string path = AssetBundleLoad.GetAbPath(); //这里得创建下文件夹,他不会帮你创建 if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } BuildPipeline.BuildAssetBundles(path, buildList.ToArray(), BuildAssetBundleOptions.UncompressedAssetBundle, EditorUserBuildSettings.activeBuildTarget); //删除多余资源 DeleteUnUsefulAssetBundle(); //把新hash变成老的 string newHashPath = GetNewHashPath(); if (File.Exists(newHashPath)) { FileTools.Copy(newHashPath, GetOldHashPath()); } //写入最新hash FileTools.WriteAllText(GetNewHashPath(), JsonMapper.ToJson(GetAllAssetbundleHashList())); Debug.Log("打包完成"); }
public static string GetVersionPath() { return(AssetBundleLoad.GetAbParentPath() + versionName); }
public static string GetHotfixZipPath() { return(AssetBundleLoad.GetAbParentPath() + hotfixZipName); }
public static string GetRemoteHashPath() { return(AssetBundleLoad.GetAbParentPath() + remoteHashName); }
public static string GetOldHashPath() { return(AssetBundleLoad.GetAbParentPath() + oldHashName); }
public IEnumerator StartLoadSceneAsync(AssetBundleLoad load) { if (!_uninstallable_scene.ContainsKey(_scene_name)) { _uninstallable_scene.Add(_scene_name, false); } _current = 0; _totalCount = 2; //最少有2个,一个ab,一个场景加载 CalculationDependencyCount(_asset_bundle_name, load); TextAsset xmlInfo = load.LoadAsset <TextAsset>(_xml_asset_bundle_name); Dictionary <XmlNode, XmlNodeList> sceneObjects = GetSceneObjects(xmlInfo); AssetBundleLoaderRequest abRequest = AssetBundleLoaderRequest.New(_asset_bundle_name); load.LoadSingleAssetBundleAsync(abRequest); while (!abRequest.IsDone) { yield return(null); } UpdateProgress(); // 加载场景依赖项 yield return(LoadDependency(_asset_bundle_name, load)); yield return(SceneManager.LoadSceneAsync(_scene_name, _load_mode)); UpdateProgress(); // 复位Object对象 if (sceneObjects != null) { var itr = sceneObjects.Keys.GetEnumerator(); while (itr.MoveNext()) // 遍历Object的节点 { XmlElement objectNode = itr.Current as XmlElement; string objectPath = objectNode.GetAttribute("Path"); string objectName = objectNode.GetAttribute("Name"); AssetLoaderRequest request = AssetLoaderRequest.New(objectPath); load.LoadAssetAsync <Object>(request); while (!request.IsDone) { yield return(null); } UpdateProgress(); GameObject gameObject = (GameObject)GameObject.Instantiate(request.asset); gameObject.name = objectName; foreach (XmlElement el in objectNode.ChildNodes) { float x = float.Parse(el.GetAttribute("X")); float y = float.Parse(el.GetAttribute("Y")); float z = float.Parse(el.GetAttribute("Z")); if (el.Name.Equals("Position")) { gameObject.transform.position = new Vector3(x, y, z); } else if (el.Name.Equals("Rotate")) { gameObject.transform.eulerAngles = new Vector3(x, y, z); } else if (el.Name.Equals("Scale")) { gameObject.transform.localScale = new Vector3(x, y, z); } } } itr.Dispose(); } UpdateProgress(); IsDone = true; if (loadCompleted != null) { loadCompleted(this); } _uninstallable_scene[_scene_name] = true; }