public static AssetsDependenctData BuildAndSave() { var resource = BuildUtils.GetAsset <AssetsDependenctData>(AssetsDependenctGenerateEditor.EditorGenerate); resource = UnityEngine.Object.Instantiate <AssetsDependenctData>(resource); resource.FixedDirty(); return(resource); }
///// <summary> ///// 检测,设置构建单个包的数据资源 ///// </summary> //static AssetBundleBuild[] BuildSinglePackage() //{ // var singleBuilds = new AssetBundleBuild[AssetBundleInfo.OnePackageTypes.Length]; // for (int oneIndex = 0; oneIndex < AssetBundleInfo.OnePackageTypes.Length; oneIndex++) // { // //进行单独打成一个包的资源数据 // var list = new List<AssetBundleInfo>(); // foreach (var result in AssetDependenctTree.resourceGraph.result) // { // var node = result.Value; // AssetBundleInfo bundle; // //获取一个没有后缀名的全路径 // var bundleKey = BuildUtils.GetPathDirWithoutExtension(node.NodePath); // if (!bundleListEx.TryGetValue(bundleKey, out bundle)) // { // bundle = new AssetBundleInfo(node, AssetDependenctTree.resourceGraph.result, bundleListEx); // bundleListEx.Add(bundleKey, bundle); // } // //检测是否为当前同种类型 // if (AssetBundleInfo.OnePackageTypes[oneIndex] == bundle.type) // { // bundle.MarkAsBuild(); // list.Add(bundle); // } // } // var singleBuild = new AssetBundleBuild(); // var assetPath = "res/" + AssetBundleInfo.OnePackageTypes[oneIndex].ToString() + extension; // singleBuild.assetBundleName = assetPath; // singleBuild.assetNames = new string[list.Count]; // for (int i = 0; i < list.Count; i++) // { // singleBuild.assetNames[i] = list[i].selfNode.NodePath; // } // singleBuilds[oneIndex] = singleBuild; // } // return singleBuilds; //} ///// <summary> ///// 构建除了单独打包之外的其他资源 ///// </summary> ///// <param name="withSubAsset"></param> //private static AssetBundleBuild[] BuildAllResourceEx(bool withSubAsset = true) //{ // var assetBundlesList = new List<AssetBundleBuild>(); // //自底层分析出来 哪个资源需要单独拆出来打包 // int maxdepth = AssetDependenctGraph.Node.MaxDepth; // //资源按照depth排序 计算出来最大的深度 // for (int i = maxdepth; i >= 0; i--) // { // var currentDepth = i; // //获取某一 depth 的所有资源数据 // var alldepth = BuildUtils.FindAll(AssetDependenctTree.resourceGraph.result, tree => tree.Depth == currentDepth); // for (int j = 0; j < alldepth.Count; j++) // { // AssetBundleInfo info; // var bundleKey = BuildUtils.GetPathDirWithoutExtension(alldepth[j].NodePath); // //如果不在资源打包列表,那么添加进来 // if (!bundleListEx.TryGetValue(bundleKey, out info)) // { // info = new AssetBundleInfo(alldepth[j], AssetDependenctTree.resourceGraph.result, bundleListEx); // Debug.Log(bundleKey); // bundleListEx.Add(bundleKey, info); // } // //查找自己被使用了几次 // info.BuildAlreadyBuildCount(); // //检测是否需要单独进行打包 // if (info.BuildAlone()) // { // //设置flag已经被放到打包列表里面了 // info.MarkAsBuild(); // var assetBundleBuild = new AssetBundleBuild(); // var assetBundleName = GetAssetNamePath(info) + extension; // assetBundleBuild.assetNames = new string[1] { info.selfNode.NodePath }; // assetBundleBuild.assetBundleName = assetBundleName; // assetBundlesList.Add(assetBundleBuild); // } // else//如果不需要单独打包 就不做任何处理 // { // } // } // } // return assetBundlesList.ToArray(); //} /// <summary> /// 检测,设置构建单个包的数据资源 /// </summary> static AssetBundleBuild[] BuildSinglePackage(Dictionary <string, AssetDependenctGraph.Node> dic) { var singleBuilds = new AssetBundleBuild[AssetBundleInfo.OnePackageTypes.Length]; for (int oneIndex = 0; oneIndex < AssetBundleInfo.OnePackageTypes.Length; oneIndex++) { //进行单独打成一个包的资源数据 var list = new List <AssetBundleInfo>(); foreach (var result in dic) { var node = result.Value; AssetBundleInfo bundle; //获取一个没有后缀名的全路径 var bundleKey = BuildUtils.GetPathDirWithoutExtension(node.NodePath); if (!bundleListEx.TryGetValue(bundleKey, out bundle)) { bundle = new AssetBundleInfo(node, dic, bundleListEx); bundleListEx.Add(bundleKey, bundle); } //检测是否为当前同种类型 if (AssetBundleInfo.OnePackageTypes[oneIndex] == bundle.type) { bundle.MarkAsBuild(); list.Add(bundle); } } var singleBuild = new AssetBundleBuild(); var assetPath = "res/" + AssetBundleInfo.OnePackageTypes[oneIndex].ToString() + extension; singleBuild.assetBundleName = assetPath; singleBuild.assetNames = new string[list.Count]; for (int i = 0; i < list.Count; i++) { singleBuild.assetNames[i] = list[i].selfNode.NodePath; } singleBuilds[oneIndex] = singleBuild; } return(singleBuilds); }
/// <summary> /// 画依赖的GUI /// </summary> private void DrawDependencyGUI() { if (resourceGraph.result.Count > 0) { EditorGUILayout.BeginHorizontal(); currentSelection = EditorGUILayout.ObjectField(currentSelection, typeof(Object), false); EditorGUILayout.EndHorizontal(); if (currentSelection) { var currentSelectionPath = AssetDatabase.GetAssetPath(currentSelection); currentSelectionPath = BuildUtils.GetUnityPath(currentSelectionPath); if (currentSelectionPath.Contains("Resources")) { AssetDependenctGraph.Node graph; if (resourceGraph.result.TryGetValue(currentSelectionPath, out graph)) { EditorGUILayout.BeginHorizontal(); var maxHeight = newGraph != null ? newGraph.maxHeight : 5000; scrollValue = GUI.BeginScrollView(new Rect(0, 20, position.width, position.height), scrollValue, new Rect(0, 0, position.width, maxHeight), true, true); BeginWindows(); if (graph.Parents != null) { if (newGraph == null || newGraph.tree != graph) { newGraph = new AssetNodeGraph(resourceGraph.result, graph); } newGraph.Draw(); } EndWindows(); GUI.EndScrollView(); EditorGUILayout.EndHorizontal(); } } } } }
/// <summary> /// 获取所有的资源引用数据信息 /// </summary> public static void UpdateAssetDependenct() { using (new ExecuteTimer("UpdateAssetDependenct")) { //获取所有的资源引用数据信息 data = GetAssetDependenctData(); //刷新存储资源引用数据 BuildUtils.RemoveAsset(EditorGenerate); BuildUtils.SaveAsset(data, EditorGenerate); EditorPrefs.SetBool(ResourceDirty, true); } }
/// <summary> /// 检测当前文件是否为shader文件 /// </summary> /// <returns></returns> public bool IsShader() { if (string.IsNullOrEmpty(NodePath)) { return(false); } string extension = BuildUtils.GetPathExtension(NodePath); if (AssetFileType.GetAssetBundleBuildType(NodePath, extension) == AssetBundleBuildType.Shader) { return(true); } return(false); }
/// <summary> /// 构建其他Child包 /// </summary> /// <param name="withSubAssets">是否在每个资源中包含依赖资源</param> internal void BuildAllUnusedAssets(bool withSubAssets = true) { if (withSubAssets) { return;//TODO 允许资源重复打包 } for (int i = 0; i < selfNode.AllChildren.Length; ++i) { string subFileName = selfNode.AllChildren[i]; if (!string.IsNullOrEmpty(subFileName)) { AssetImporter importer = AssetImporter.GetAtPath(subFileName); BuildUtils.SetAssetBundleName(importer, this.bundleName); } } }
/// <summary> /// 修复所有的关联关系 /// </summary> public void FixedDirty() { foreach (var i in data.GetDic()) { if (i.Value.isdirty) { if (File.Exists(i.Key)) { i.Value.dependencies = BuildUtils.ExceptScriptAndDll(BuildUtils.GetDependencies(i.Key)); i.Value.isdirty = false; } else { Debug.Log(i.Key + " is delete!"); } } } EditorUtility.SetDirty(this); }
public void Update() { for (int fast = 0; fast < 10; fast++) { if (isPermission && files != null) { if (index < files.Length) { var assetPath = BuildUtils.GetUnityPath(files[index]); var denpendenctList = new DependenctList(); denpendenctList.dependencies = BuildUtils.ExceptScriptAndDll(BuildUtils.GetDependencies(assetPath)); denpendenctList.isdirty = false; data.data.Add(assetPath, denpendenctList); EditorUtility.DisplayProgressBar("正在生成资源依赖图", "进度:" + (index / (float)files.Length) * 100 + "%", ++index / (float)files.Length); } else { Debug.Log(data.data.Count + "HashCode:::" + data.data.GetHashCode()); isPermission = false; EditorUtility.ClearProgressBar(); BuildUtils.RemoveAsset(EditorGenerate); BuildUtils.SaveAsset(data, EditorGenerate); EditorPrefs.SetBool(ResourceDirty, true); data = null; } } } }
/// <summary> /// 获取当前所有的资源引用数据 /// </summary> /// <returns></returns> static AssetsDependenctData GetAssetDependenctData() { var allFile = GetAllFile(); AssetsDependenctData data = ScriptableObject.CreateInstance <AssetsDependenctData>(); data.data = new AssetsDependenct(); for (int i = 0; i < allFile.Length; i++) { var assetPath = BuildUtils.GetUnityPath(allFile[i]); var list = new DependenctList(); list.dependencies = BuildUtils.ExceptScriptAndDll(BuildUtils.GetDependencies(assetPath)); list.isdirty = false; data.data.Add(assetPath, list); } return(data); }
/// <summary> /// 按照目录进行打包 /// </summary> static AssetBundleBuild[] BuildDirectoryPackage(Dictionary <string, AssetDependenctGraph.Node> all) { List <AssetBundleBuild> singleBuilds = new List <AssetBundleBuild>(); //需要进行目录打包的资源 Dictionary <string, List <AssetBundleInfo> > dic = new Dictionary <string, List <AssetBundleInfo> >(); for (int oneIndex = 0; oneIndex < AssetBundleInfo.DirectoryTypes.Length; oneIndex++) { foreach (var result in all) { var node = result.Value; AssetBundleInfo bundle; //获取一个没有后缀名的全路径 var bundleKey = BuildUtils.GetPathDirWithoutExtension(node.NodePath); if (!bundleListEx.TryGetValue(bundleKey, out bundle)) { bundle = new AssetBundleInfo(node, all, bundleListEx); bundleListEx.Add(bundleKey, bundle); } //检测是否为当前同种类型 if (AssetBundleInfo.DirectoryTypes[oneIndex] == bundle.type) { bundle.MarkAsBuild(); string url = Path.GetDirectoryName(node.NodePath); if (dic.ContainsKey(url)) { dic[url].Add(bundle); } else { List <AssetBundleInfo> list = new List <AssetBundleInfo>(); list.Add(bundle); dic[url] = list; } } } foreach (var item in dic) { var singleBuild = new AssetBundleBuild(); var assetPath = AssetPathRule.GetDirectoryBuildBundlePath(item.Key) + extension; singleBuild.assetBundleName = assetPath; var list = item.Value; singleBuild.assetNames = new string[list.Count]; for (int i = 0; i < list.Count; i++) { singleBuild.assetNames[i] = list[i].selfNode.NodePath; } singleBuilds.Add(singleBuild); } } return(singleBuilds.ToArray()); }
/// <summary> /// 开始构建 AssetBundle /// </summary> /// <param name="target"></param> static void BuildAssetBundle(BuildTarget buildTarget, int compre_type, bool is_force_build, string[] build_asset_arr) { //生成资源的依赖关系 AssetsDependenctGenerateEditor.UpdateAssetDependenct(); //构建引用关系图形 AssetDependenctTree.BuildAssetDependenctGraph(); //更新资源打包后缀 UpAssetExtension(buildTarget); //获取所有需要打包的资源数据引用 var dic = AllNeedBuildAssetDependenct(build_asset_arr); //获取资源进行单独打包的列表 var singles = BuildSinglePackage(dic); //获取目录资源打包 var directory = BuildDirectoryPackage(dic); //获取资源进行除单独打包的列表 var resources = BuildAllResourceEx(dic); //获取总共需要进行打包的资源数据 var builds = ArrayTools.Concat(singles, directory, resources); //var exportDir = BuildUtils.CreateAssetBundleDir(buildTarget, out_path);//构建不同平台的子目录 //var fullversion = BuildUtils.GetCurrentPackageVersion(); //var bundleName = BuildUtils.GetAssetBundleName(buildTarget); //int major, minor, build; //VersionJson.GetResVersion(fullversion, out major, out minor, out build); //var version = build.ToString().PadLeft(VersionJson.VersionCount, '0'); //var versionPath = BuildUtils.GenVersionPath(__versionPath, version); //AssetBundleManifest assetBundlemainfest; //if (build > 0)//小版本的情况 //{ // Debug.Log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!build version" + version); // //如果某一个版本的文件存在 就全部删除掉. // if (Directory.Exists(versionPath)) // { // Directory.Delete(versionPath, true); // } // //不强制打包 小幅度增加版本号,以上一个版本的数据比较变动 // assetBundlemainfest = BuildBundlesUnity5(exportDir, __compressType, __buildTarget, false, builds); // if (assetBundlemainfest != null) // { // var staticManifest = BuildUtils.GetStaticAssetBundleManifest(lastVersionPath, bundleName); // var filePath = lastVersionPath; // if (staticManifest != null) // { // string[] addResource, deleteResource, updateResource; // BuildUtils.BuildVersionMergeInfomation(filePath, exportDir, staticManifest, assetBundlemainfest, out addResource, out deleteResource, out updateResource); // CopyResourceToVersionFile(addResource, updateResource, exportDir, versionPath); // CopyAssetBundleManifestFile(exportDir, versionPath, __buildTarget); // CreateVersionFile(versionPath, fullversion, __buildTarget); // //生成信息中需要包含新增资源 删除资源 更新资源 // GenLittleVersionChange(addResource, updateResource, deleteResource, versionPath); // } // else // { // Debug.LogError("Error!!,Last Version Is Empty!" + version); // } // } // else // { // Debug.LogError("Error! AssetBundleMainfest is Null."); // } //} //else//大版本的情况 //{ // if (Directory.Exists(versionPath)) // { // Directory.Delete(versionPath, true); // } // Debug.Log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!build version" + version); // //强制重新生成,全部拷贝到一个新的目录 更新大版本 生成到StreamingPath // assetBundlemainfest = BuildBundlesUnity5(exportDir, __compressType, __buildTarget, true, builds); // if (assetBundlemainfest != null) // { // //到version目录 1 2 3 // CopyAssetBundleManifestFile(exportDir, versionPath, __buildTarget); // //备份文件到Version文件版本库中 虽然以后不用使用 但是需要提取版本变化文件 // CopyResourceToVersionFile(assetBundlemainfest.GetAllAssetBundles(), null, exportDir, versionPath); // CreateVersionFile(versionPath, fullversion, __buildTarget); // //到streaming目录 1 2 3 // CopyResouceToStreamingAssets(assetBundlemainfest, exportDir, __buildTarget); // CopyVersionToStreamingAssets(versionPath, __buildTarget); // CopyAssetBundleManifestToStreamingAssets(exportDir, __buildTarget); // //拷贝到游戏里面 供下一个打包流程使用 // } // else // { // Debug.LogError("Error! AssetBundleMainfest is Null."); // } //} ////比对文件 //if (__withMD5 && assetBundlemainfest != null) //{ // var bundlexList = CreateBundleMD5(assetBundlemainfest, exportDir); // ProcessVersion(exportDir, bundlexList); // //处理StreamingAsset里面的资源 // ChangeBundleNameToMd5(exportDir, bundlexList); //} //获取AssetBundle输出目录 string out_path = GetAssetBundleOutPath(); AssetBundleManifest assetBundlemainfest; //不强制打包 小幅度增加版本号,以上一个版本的数据比较变动 assetBundlemainfest = BuildAssetBundle(out_path, compre_type, buildTarget, is_force_build, builds); if (assetBundlemainfest != null) { Debug.Log("资源数据打包完成 ~~~ "); //存储引用数据记录 ManifestTools.OnSaveManifest(out_path + "/Data", assetBundlemainfest); //var staticManifest = BuildUtils.GetStaticAssetBundleManifest(lastVersionPath, bundleName); //var filePath = lastVersionPath; //if (staticManifest != null) //{ // string[] addResource, deleteResource, updateResource; // BuildUtils.BuildVersionMergeInfomation(filePath, exportDir, staticManifest, assetBundlemainfest, out addResource, out deleteResource, out updateResource); // CopyResourceToVersionFile(addResource, updateResource, exportDir, versionPath); // CopyAssetBundleManifestFile(exportDir, versionPath, __buildTarget); // CreateVersionFile(versionPath, fullversion, __buildTarget); // //生成信息中需要包含新增资源 删除资源 更新资源 // GenLittleVersionChange(addResource, updateResource, deleteResource, versionPath); //} //else //{ // Debug.LogError("Error!!,Last Version Is Empty!" + version); //} } else { Debug.LogError("Error! AssetBundleMainfest is Null."); } //清理环境 EditorUtility.UnloadUnusedAssetsImmediate(); //更新资源列表 BuildUtils.Refresh(); }
/// <summary> /// 比对两个Manifest的差异 /// </summary> public static void BuildVersionMergeInfomation(string oldbasePath, string newbasePath, AssetBundleManifest baseManifest, AssetBundleManifest afterManifest, out string[] addResource, out string[] deleteResource, out string[] updateResource) { var allAssetBundle = baseManifest.GetAllAssetBundles(); var afterAllAssetBundle = afterManifest.GetAllAssetBundles(); //新增加的资源列表 addResource = afterAllAssetBundle.Except(allAssetBundle).ToArray(); //addResource.Each(s => Debug.Log("Update::::::::::::::::::" + s)); //删除的资源列表 deleteResource = allAssetBundle.Except(afterAllAssetBundle).ToArray(); //deleteResource.Each(s => Debug.Log("Update::::::::::::::::::" + s)); //两边都存在的资源 var unionResource = allAssetBundle.Intersect(afterAllAssetBundle).ToArray(); //更新的资源列表 var updateResourceList = new List <string>(); for (int i = 0; i < unionResource.Length; i++) { if (baseManifest.GetAssetBundleHash(unionResource[i]) != afterManifest.GetAssetBundleHash(unionResource[i])) { updateResourceList.Add(unionResource[i]); } else { //Fixed Unity Script Not Change BUG //相等的情况下比对MD5 查看是否需要更新脚本 当脚本需要更新的时候 需要打大版本 var oldFilePath = Path.Combine(oldbasePath, unionResource[i]); var newFilePath = Path.Combine(newbasePath, unionResource[i]); var md5 = BuildUtils.Md5(oldFilePath, false); var newMD5 = BuildUtils.Md5(newFilePath, false); //Debug.Log(oldFilePath + " " + newFilePath + " MD5:" + md5 + " new MD5" + newMD5); if (md5 != newMD5) { updateResourceList.Add(unionResource[i]); //Debug.LogFormat("Changed!!!:{0},oldFilePath:{1},NewFilePath:{2}", unionResource[i], oldFilePath, newFilePath); //Debug.Log("Changed!!! " + unionResource[i]); Debug.LogError("We need Build a Big Version " + unionResource[i] + " is modify."); } else { //Debug.Log("No change" + unionResource[i]); } } } updateResource = updateResourceList.ToArray(); //updateResource.Each(s => Debug.Log("Update::::::::::::::::::" + s)); }