public static void BuildGame(string resourcesFolder, GameAssetsManifest manifest) { Console.WriteLine("Building Game Asssets..."); ResourceLoader.SetRootPath(resourcesFolder); List <ResourcePak> resource_paks = BuildProjectResources(manifest); foreach (var pak in resource_paks) { using var pak_file = File.Create(Path.Combine(resourcesFolder, pak.Name + ".pak")); MessagePackSerializer.Serialize(pak_file, pak); } Console.WriteLine("Project Built Successfully"); }
public void Build(BuildActionArgs args) { try { var json_game_info = File.ReadAllText(Path.Combine(args.GameFolder, "project.json")); GameInfo game_info = JsonSerializer.Deserialize <GameInfo>(json_game_info); var resources_folder = Path.Combine(args.GameFolder, game_info.ResourcesFolder); GameAssetsManifest assets_manifest = ResourceLoader.LoadGameAssetsManifest(resources_folder); Builder.BuildGame(resources_folder, assets_manifest); } catch (Exception e) { Console.WriteLine(e); } }
static void ResourcesHandle(string resPath) { if (!Directory.Exists(resPath)) { Directory.CreateDirectory(resPath); } //固定打包目标 string[] respath = new string[] { Application.dataPath + "/ArtAssets", Application.dataPath + "/Prefabs", Application.dataPath + "/Shaders" }; List <AssetBundleBuild> abbList = BuildManager.GetBuildAll(); Debug.Log("收集需要打包的场景"); //收集需要打包的场景 foreach (EditorBuildSettingsScene item in EditorBuildSettings.scenes) { if (!item.enabled || item.path.Contains("GameInitialize.unity")) { continue; } AssetBundleBuild abb = new AssetBundleBuild(); string bname = item.path.Replace(".unity", FXGame.AppConst.ExtName); if (string.IsNullOrEmpty(bname)) { continue; } abb.assetBundleName = bname.Substring(7); abb.assetNames = new string[] { item.path }; //item.path.ToLower() == assets / scenes / gamescenes / scene1.unity //abb.assetBundleName.ToLower() == item.path.ToLower() BuildManager.idxMap[item.path.ToLower()] = abb.assetBundleName.ToLower(); abbList.Add(abb); } AssetBundleManifest info = BuildPipeline.BuildAssetBundles(resPath, abbList.ToArray(), options, target); Debug.Log(info); //因为AssetBundleManifest只是一个信息列表,不能通过path找到包,不能查找关联包 //要建立一个管理器,来处理需求 //这里面有key,关联ab包, 让我们可以通过路径,查找到所在ab包 string[] abs = info.GetAllAssetBundles(); GameAssetsManifest gameAssetsManifest = ScriptableObject.CreateInstance <GameAssetsManifest>(); gameAssetsManifest.buildPath = resPath; //压缩方式 if ((options & BuildAssetBundleOptions.ChunkBasedCompression) == BuildAssetBundleOptions.ChunkBasedCompression) { gameAssetsManifest.m_Compression = GameAssetsManifest.AssetBundleCompression.LZ4; } else if ((options & BuildAssetBundleOptions.UncompressedAssetBundle) == BuildAssetBundleOptions.UncompressedAssetBundle) { gameAssetsManifest.m_Compression = GameAssetsManifest.AssetBundleCompression.None; } else { gameAssetsManifest.m_Compression = GameAssetsManifest.AssetBundleCompression.LZMA; } gameAssetsManifest.AddAssetBundleManifest(info); gameAssetsManifest.AddAssetIdxMap(BuildManager.idxMap); //这里的目的是将 GameAssetsManifest 虚拟的管理器,转换成可以在unity显示的二进制文件 string manifestPath = "Assets/GameAssetsManifest.asset"; AssetDatabase.CreateAsset(gameAssetsManifest, manifestPath); AssetDatabase.Refresh(); //能打ab包的必须是资源,将转换为二进制文件的GameAssetsManifest,打成ab包 AssetBundleBuild ab = new AssetBundleBuild(); ab.assetBundleName = "manifest" + FXGame.AppConst.ExtName; ab.assetNames = new string[] { manifestPath }; BuildPipeline.BuildAssetBundles(resPath, new AssetBundleBuild[] { ab }, options, target); Debug.Log(Application.dataPath + "/" + "GameAssetsManifest.asset"); //F:/MyGame/AssetsGameAssetsManifest.asset Debug.Log(resPath + "/" + ab.assetBundleName + ".manifest"); //F:/MyGame/Assets\../AssetBundles\win\resmanifest.png.manifest File.Delete(Application.dataPath + "GameAssetsManifest.asset"); File.Delete(resPath + ab.assetBundleName + ".manifest"); }
//private static void BuildAppConfigFile(string root_path, AppProject project) //{ // GameProperties props = new GameProperties() // { // Title = project.Title, // FrameRate = project.FrameRate, // CanvasWidth = project.CanvasWidth, // CanvasHeight = project.CanvasHeight, // Fullscreen = project.StartFullscreen, // PreloadResourcePaks = project.PreloadPaks // }; // File.WriteAllBytes(Path.Combine(root_path, "Config.json"), // JsonSerializer.PrettyPrintByteArray(JsonSerializer.Serialize(props))); //} private static List <ResourcePak> BuildProjectResources(GameAssetsManifest manifest) { var resource_groups = manifest.Resources; var results = new List <ResourcePak>(); foreach (var(groupKey, group) in resource_groups) { var pak = new ResourcePak(groupKey); Console.WriteLine($"Creating resource Pak: {pak.Name}"); if (group.Images != null) { foreach (var image_info in group.Images) { var pixmap_data = ImageBuilder.Build(image_info.Id, image_info.Path); pak.Images.Add(image_info.Id, pixmap_data); pak.TotalResourcesCount++; Console.WriteLine($"Added Image: {pixmap_data.Id}"); } } if (group.Shaders != null) { foreach (var shader_info in group.Shaders) { var shader_data = ShaderBuilder.Build(shader_info.Id, shader_info.VsPath, shader_info.FsPath); pak.Shaders.Add(shader_info.Id, shader_data); pak.TotalResourcesCount++; Console.WriteLine($"Added Shader: {shader_data.Id}"); } } if (group.Fonts != null) { foreach (var font_info in group.Fonts) { var build_params = new FontBuildParams() { Id = font_info.Id, LineSpacing = font_info.LineSpacing, Spacing = font_info.Spacing, DefaultChar = font_info.DefaultChar, Faces = font_info.Faces.Select(f => new FontFace() { CharRanges = f.CharRanges.Select(CharRange.GetFromKey).ToList(), Path = f.Path, Size = f.Size, }).ToList() }; var font_data = FontBuilder.Build(build_params); pak.Fonts.Add(font_info.Id, font_data); pak.TotalResourcesCount++; Console.WriteLine($"Added Font: {font_data.Id}"); } } if (group.Atlases != null) { foreach (var atlas_info in group.Atlases) { var atlas_data = AtlasBuilder.Build(atlas_info.Id, atlas_info.Path, atlas_info.Regions); pak.Atlases.Add(atlas_data.Id, atlas_data); pak.TotalResourcesCount++; Console.WriteLine($"Added Atlas: {atlas_data.Id}"); } } if (group.TextFiles != null) { foreach (var text_file_info in group.TextFiles) { var text_file_data = TextBuilder.Build(text_file_info.Id, text_file_info.Path); pak.TextFiles.Add(text_file_info.Id, text_file_data); pak.TotalResourcesCount++; Console.WriteLine($"Added TextFile: {text_file_data.Id}"); } } results.Add(pak); Console.WriteLine($"Built PAK with {pak.TotalResourcesCount} resources."); } return(results); }
//private static void BuildAppConfigFile(string root_path, AppProject project) //{ // GameProperties props = new GameProperties() // { // Title = project.Title, // FrameRate = project.FrameRate, // CanvasWidth = project.CanvasWidth, // CanvasHeight = project.CanvasHeight, // Fullscreen = project.StartFullscreen, // PreloadResourcePaks = project.PreloadPaks // }; // File.WriteAllBytes(Path.Combine(root_path, "Config.json"), // JsonSerializer.PrettyPrintByteArray(JsonSerializer.Serialize(props))); //} private static List <ResourcePak> BuildProjectResources(GameAssetsManifest manifest) { var resource_groups = manifest.Resources; var results = new List <ResourcePak>(); foreach (var resource_group in resource_groups) { var pak = new ResourcePak(resource_group.Key); Console.WriteLine($"Creating resource Pak: {pak.Name}"); if (resource_group.Value.Images != null) { foreach (var image_info in resource_group.Value.Images) { var pixmap_data = ImageBuilder.Build(image_info.Id, image_info.Path); pak.Images.Add(image_info.Id, pixmap_data); pak.TotalResourcesCount++; Console.WriteLine($"Added Image: {pixmap_data.Id}"); } } if (resource_group.Value.Shaders != null) { foreach (var shader_info in resource_group.Value.Shaders) { var shader_data = ShaderBuilder.Build(shader_info.Id, shader_info.VsPath, shader_info.FsPath); pak.Shaders.Add(shader_info.Id, shader_data); pak.TotalResourcesCount++; Console.WriteLine($"Added Shader: {shader_data.Id}"); } } if (resource_group.Value.Fonts != null) { foreach (var font_info in resource_group.Value.Fonts) { var build_params = new FontBuildParams() { Id = font_info.Id, Path = font_info.Path, Size = font_info.Size, CharRangeLevel = font_info.CharRangeLevel, PaddingLeft = font_info.Padding != null ? font_info.Padding[0] : 0, PaddingRight = font_info.Padding != null ? font_info.Padding[1] : 0, PaddingUp = font_info.Padding != null ? font_info.Padding[2] : 0, PaddingDown = font_info.Padding != null ? font_info.Padding[3] : 0, DropShadow = font_info.DropShadow, ShadowOffsetX = font_info.ShadowOffsetX, ShadowOffsetY = font_info.ShadowOffsetY, ShadowColor = font_info.ShadowColor != null?Color.FromHex(font_info.ShadowColor) : Color.Black }; var font_data = FontBuilder.Build(build_params); pak.Fonts.Add(font_info.Id, font_data); pak.TotalResourcesCount++; Console.WriteLine($"Added Font: {font_data.Id}"); } } if (resource_group.Value.Atlases != null) { foreach (var atlas_info in resource_group.Value.Atlases) { var atlas_data = AtlasBuilder.Build(atlas_info.Id, atlas_info.Path, atlas_info.Regions); pak.Atlases.Add(atlas_data.Id, atlas_data); pak.TotalResourcesCount++; Console.WriteLine($"Added Atlas: {atlas_data.Id}"); } } if (resource_group.Value.TextFiles != null) { foreach (var text_file_info in resource_group.Value.TextFiles) { var text_file_data = TextBuilder.Build(text_file_info.Id, text_file_info.Path); pak.TextFiles.Add(text_file_info.Id, text_file_data); pak.TotalResourcesCount++; Console.WriteLine($"Added TextFile: {text_file_data.Id}"); } } results.Add(pak); Console.WriteLine($"Built PAK with {pak.TotalResourcesCount} resources."); } return(results); }
/// <summary> /// 生成文件索引列表信息 /// </summary> /// <param name="path"></param> /// <param name="isSperate"></param> /// <param name="target"></param> public static void BuildFileIndex(string path, bool isSperate = false, BuildTarget target = BuildTarget.Android) { Dictionary <string, int> firstMap = new Dictionary <string, int>(); Dictionary <string, int> FrontMap = new Dictionary <string, int>(); Dictionary <string, int> GuildeMap = new Dictionary <string, int>(); if (isSperate) { string[] lines = File.ReadAllLines(Util.DataPath2 + "/first.txt"); string baseDir = Util.DataPath2 + GetBuildOsDir(target) + "/"; foreach (var item in lines) { string resName = item.Replace("//", "/").Replace(baseDir, "").ToLower(); firstMap[resName] = 0; } lines = File.ReadAllLines(Util.DataPath2 + "/guildeLoad.txt"); int o = 1; foreach (var l in lines) { GuildeMap["res/" + l] = o++; } o = 1; lines = File.ReadAllLines(Util.DataPath2 + "/frontLoad.txt"); foreach (var li in lines) { FrontMap["res/" + li] = o++; } } string resPath = path.Replace("\\", "/"); ///----------------------创建文件列表----------------------- string newFilePath = resPath + "/files.txt"; if (File.Exists(newFilePath)) { File.Delete(newFilePath); } List <string> files = new List <string>(); Recursive(resPath, files); FileStream fs = new FileStream(newFilePath, FileMode.CreateNew); StreamWriter sw = new StreamWriter(fs); for (int i = 0; i < files.Count; i++) { string file = files[i]; long size = new FileInfo(file).Length; //string ext = Path.GetExtension(file); if (file.EndsWith(".meta") || file.Contains(".DS_Store") || file.EndsWith(".manifest") || file.Contains("version.txt")) { continue; } string lpath = file.Substring(resPath.Length + 1); string md5 = ""; string value = ""; string md5_read = ""; if (lpath == FXGame.Util.AppUpdateFile || lpath == "server_res_list_md5.txt") { continue; } int downloadLevel = (int)DownLoadLevel.Low; int order = 0; int resType = 0; string fname = Path.GetFileNameWithoutExtension(file);// if (lpath.StartsWith("res") && lpath.Contains(AppConst.ExtName) && fname != "manifest") { string abmPath = ""; if (null == abm) { abmPath = path + "/res/manifest" + AppConst.ExtName; abmPath = abmPath.Replace("\\", "/"); if (!File.Exists(abmPath)) { continue; } AssetBundle ab = AssetBundle.LoadFromFile(abmPath); UnityEngine.Object[] names = ab.LoadAllAssets(); foreach (var item in names) { Debug.Log(item.name); } abm = ab.LoadAsset <GameAssetsManifest>("GameAssetsManifest"); ab.Unload(false); } string bname = lpath.Substring(4); md5 = abm.GetAssetBundleHash(bname).ToString(); } else { md5 = Util.md5file(file); md5_read = md5; } if (string.IsNullOrEmpty(md5)) { continue; } else { md5_read = Util.md5file(file); } value = file.Replace(resPath, string.Empty).Substring(1); value = file.Replace(resPath, string.Empty).Substring(1); int tmp = 0; if (isSperate && GuildeMap.TryGetValue(value, out order)) { downloadLevel = (int)DownLoadLevel.Middle; order = tmp; } if (FrontMap.TryGetValue(value, out tmp)) { downloadLevel = (int)DownLoadLevel.Highest; order = tmp; } if (!isSperate || value.StartsWith("lua/lua") || (firstMap != null && firstMap.TryGetValue(value, out tmp))) { downloadLevel = 0; order = tmp; } if (value == Util.AppDllFile) { downloadLevel = 0; } sw.WriteLine(value + "|" + md5 + "|" + size + "|" + resType + "|" + downloadLevel + "|" + order + "|" + md5_read); } abm = null; sw.Close(); fs.Close(); }