using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; namespace SFramework.Editor { public static class SAssetsBundleHelper { static string ResourcesBuildDir { get { var dir = "Assets/" + SFrameworkDef.ResourceDir + "/"; return dir; } } /// /// Unity 5新AssetBundle系统,需要为打包的AssetBundle配置名称 /// /// 直接将KEngine配置的BundleResources目录整个自动配置名称,因为这个目录本来就是整个导出 /// [MenuItem("SFramework/AssetBundle/Auto Set Names To [BundleResources]")] public static void AutoSetAssetBundleNames() { var dir = ResourcesBuildDir; // Check marked asset bundle whether real foreach (var assetGuid in AssetDatabase.FindAssets("")) { var assetPath = AssetDatabase.GUIDToAssetPath(assetGuid); var assetImporter = AssetImporter.GetAtPath(assetPath); var bundleName = assetImporter.assetBundleName; if (string.IsNullOrEmpty(bundleName)) { continue; } if (!assetPath.StartsWith(dir)) { assetImporter.assetBundleName = null; } } // set BundleResources's all bundle name foreach (var filepath in System.IO.Directory.GetFiles(dir, "*.*", System.IO.SearchOption.AllDirectories)) { if (filepath.EndsWith(".meta")) continue; var importer = AssetImporter.GetAtPath(filepath); if (importer == null) { Debug.LogError(string.Format("Not found: {0}", filepath)); continue; } var bundleName = filepath.Substring(dir.Length, filepath.Length - dir.Length); importer.assetBundleName = bundleName + SFrameworkDef.AssetsBundleExtName; } Debug.Log("Make all asset name success!"); } /// /// 清理冗余,即无此资源,却存在AssetBundle的文件, Unity 5 only /// [MenuItem("SFramework/AssetBundle/Clean Redundancies")] public static void CleanAssetBundlesRedundancies() { var platformName = SPlatformInfo.GetBuildPlatformName(); var outputPath = GetExportPath(EditorUserBuildSettings.activeBuildTarget); var srcList = new List(System.IO.Directory.GetFiles(ResourcesBuildDir, "*.*", System.IO.SearchOption.AllDirectories)); for (var i = srcList.Count - 1; i >= 0; i--) { if (srcList[i].EndsWith(".meta")) srcList.RemoveAt(i); else srcList[i] = srcList[i].Replace(ResourcesBuildDir, "").ToLower(); } var toListMap = new Dictionary(); var toList = new List(System.IO.Directory.GetFiles(outputPath, "*.*", System.IO.SearchOption.AllDirectories)); for (var i = toList.Count - 1; i >= 0; i--) { var filePath = toList[i]; if (toList[i].EndsWith((".meta")) || toList[i].EndsWith(".manifest")) { toList.RemoveAt(i); } else { var rName = toList[i].Replace(outputPath, ""); if (rName == platformName || // 排除AB 平台总索引文件, rName == (platformName + ".manifest") || rName == (platformName + ".meta") || rName == (platformName + ".manifest.meta")) { toList.RemoveAt(i); } else { // 去掉扩展名,因为AssetBundle额外扩展名 toList[i] = System.IO.Path.ChangeExtension(rName, "");// 会留下最后句点 toList[i] = toList[i].Substring(0, toList[i].Length - 1); // 去掉句点 toListMap[toList[i]] = filePath; } } } // 删文件和manifest for (var i = 0; i < toList.Count; i++) { if (!srcList.Contains(toList[i])) { var filePath = toListMap[toList[i]]; var manifestPath = filePath + ".manifest"; System.IO.File.Delete(filePath); Debug.LogWarning("Delete... " + filePath); if (System.IO.File.Exists(manifestPath)) { System.IO.File.Delete(manifestPath); Debug.LogWarning("Delete... " + manifestPath); } } } } [MenuItem("SFramework/AssetBundle/Create Version File")] public static void CreateVersionFile() { AssetBundle.UnloadAllAssetBundles(true); var platformName = SPlatformInfo.GetBuildPlatformName(); var outputPath = GetExportPath(EditorUserBuildSettings.activeBuildTarget); Debug.Log(string.Format("CreateVersionFile -> platformName:{0} outputPath:{1}", platformName, outputPath)); // Load manifestAB string manifestABPath = Application.dataPath + "/../Product/Bundles/" + platformName + "/" + platformName; Debug.Log("manifestABPath -> " + manifestABPath); byte[] byManifest = System.IO.File.ReadAllBytes(manifestABPath); AssetBundle manifestAB = AssetBundle.LoadFromMemory(byManifest); if (manifestAB == null) { Debug.LogError("CreateVersionFile -> Get ManifestAB Failed. Path:" + manifestABPath); return; } AssetBundleManifest manifest = manifestAB.LoadAsset("AssetBundleManifest") as AssetBundleManifest; if (manifest == null) { Debug.LogError("CreateVersionFile -> Get Manifest From AssetBundle Failed."); return; } SVersionInfo curVersionInfo = new SVersionInfo(); curVersionInfo.version = 0; curVersionInfo.fileInfo = new List(); // Add Manifest File string manifestFileName = platformName; SFileInfo manifestFileInfo = SToolFunction.CreateFileInfo(manifestFileName, outputPath + manifestFileName); curVersionInfo.fileInfo.Add(manifestFileInfo); // Add Manifest Ext File(platform.manifest) string manifestExtFileName = platformName + ".manifest"; SFileInfo manifestExtFileInfo = SToolFunction.CreateFileInfo(manifestExtFileName, outputPath + manifestExtFileName); curVersionInfo.fileInfo.Add(manifestExtFileInfo); // Add files in manifest. string[] allABName = manifest.GetAllAssetBundles(); curVersionInfo.fileCount = allABName.Length; foreach (string abName in allABName) { string oneABFullPathWithName = outputPath + abName; SFileInfo curFileInfo = SToolFunction.CreateFileInfo(abName, oneABFullPathWithName); curFileInfo.hashInfo = manifest.GetAssetBundleHash(abName).ToString(); curVersionInfo.fileInfo.Add(curFileInfo); // Debug.Log(string.Format("oneAB:{0} Size:{1}", abName, oneABFileInfo.Length)); Debug.Log(string.Format("abName: {0} FileSize:{1} HashCode: {2}", curFileInfo.fileName, curFileInfo.fileSize, curFileInfo.hashInfo)); } string jsonString = LitJson.JsonMapper.ToJson(curVersionInfo); Debug.Log("jsonString -> " + jsonString); string jsonPath = Application.dataPath + "/../Product/Bundles/" + platformName + "/" + SFrameworkDef.VersionFileName; System.IO.StreamWriter build_info = new System.IO.StreamWriter(jsonPath); build_info.Write(jsonString); build_info.Close(); build_info.Dispose(); manifestAB.Unload(true); Debug.Log("CreateVersionFile Success!"); } //[MenuItem("SFramework/AssetBundle/Build All to All Platforms")] //public static void BuildAllAssetBundlesToAllPlatforms() //{ // var platforms = new List() // { // BuildTarget.iOS, // BuildTarget.Android, // BuildTarget.StandaloneWindows, // BuildTarget.StandaloneOSX, // }; // // Build all support platforms asset bundle // var currentBuildTarget = EditorUserBuildSettings.activeBuildTarget; // platforms.Remove(currentBuildTarget); // BuildAllAssetBundles(); // foreach (var platform in platforms) // { // if (EditorUserBuildSettings.SwitchActiveBuildTarget(platform)) // BuildAllAssetBundles(); // } // // revert platform // EditorUserBuildSettings.SwitchActiveBuildTarget(currentBuildTarget); //} [MenuItem("SFramework/AssetBundle/ReBuild All")] public static void ReBuildAllAssetBundles() { var outputPath = GetExportPath(EditorUserBuildSettings.activeBuildTarget); System.IO.Directory.Delete(outputPath, true); Debug.Log("Delete folder: " + outputPath); BuildAllAssetBundles(); } [MenuItem("SFramework/AssetBundle/Build All %&b")] public static void BuildAllAssetBundles() { if (EditorApplication.isPlaying) { Debug.LogError("Cannot build in playing mode! Please stop!"); return; } AutoSetAssetBundleNames(); var outputPath = GetExportPath(EditorUserBuildSettings.activeBuildTarget); Debug.Log(string.Format("Asset bundle start build to: {0}", outputPath)); BuildPipeline.BuildAssetBundles(outputPath, BuildAssetBundleOptions.DeterministicAssetBundle, EditorUserBuildSettings.activeBuildTarget); //BuildPipeline.BuildAssetBundles(outputPath, BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.AppendHashToAssetBundleName, EditorUserBuildSettings.activeBuildTarget); CreateVersionFile(); } /// /// Extra Flag -> ex: Android/ AndroidSD/ AndroidHD/ /// /// /// public static string GetExportPath(BuildTarget platfrom) { //string basePath = // System.IO.Path.GetFullPath(KEngine.AppEngine.GetConfig(KEngineDefaultConfigs.AssetBundleBuildRelPath)); string basePath = SFrameworkDef.AssetsBundleProductDir; if (System.IO.File.Exists(basePath)) { SAssetsBundleHelper.ShowDialog("路径配置错误: " + basePath); throw new System.Exception("路径配置错误"); } if (!System.IO.Directory.Exists(basePath)) { System.IO.Directory.CreateDirectory(basePath); } string path = null; var platformName = SPlatformInfo.GetBuildPlatformName(); path = basePath + "/" + platformName + "/"; if (!System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); } return path; } public static void ClearConsole() { System.Reflection.Assembly assembly = System.Reflection.Assembly.GetAssembly(typeof(SceneView)); System.Type type = assembly.GetType("UnityEditorInternal.LogEntries"); System.Reflection.MethodInfo method = type.GetMethod("Clear"); method.Invoke(null, null); } public static bool ShowDialog(string msg, string title = "提示", string button = "确定") { return EditorUtility.DisplayDialog(title, msg, button); } public static void ShowDialogSelection(string msg, System.Action yesCallback) { if (EditorUtility.DisplayDialog("确定吗", msg, "是!", "不!")) { yesCallback(); } } } }