/// <summary> /// 活的构建的数据 /// </summary> /// <param name="manifestPath"></param> /// <returns></returns> private static List <AssetBundleBuild> GenerateAssetBundleBuildData(DLCItem dlc) { if (dlc.IsInternal) { PackedAssets_Internal.Clear(); } else if (dlc.IsNative) { PackedAssets_Native.Clear(); } PackedAssets_DLC.Clear(); Builds.Clear(); Rules.Clear(); AllDependencies.Clear(); AllAssets.Clear(); AllBundles.Clear(); AllSharedBundles.Clear(); //建立其他文件 List <BuildRuleConfig> tempBuildDatas = dlc.BuildRuleData; if (tempBuildDatas == null && tempBuildDatas.Count == 0) { CLog.Error("没有配置相关的AssetBundle信息"); return(null); } foreach (var item in tempBuildDatas) { BuildRule buildRule = null; if (item.BuildRuleType == BuildRuleType.Directroy) { buildRule = new BuildAssetsWithDirectroy(dlc, item); } else if (item.BuildRuleType == BuildRuleType.FullPath) { buildRule = new BuildAssetsWithPath(dlc, item); } else if (item.BuildRuleType == BuildRuleType.File) { buildRule = new BuildAssetsWithFile(dlc, item); } Rules.Add(buildRule); } //搜集依赖的资源 foreach (var item in Rules) { CollectDependencies(item.Config.FullSearchPath); } //打包共享的资源 BuildSharedAssets(dlc); foreach (var item in Rules) { item.Build(); } EditorUtility.ClearProgressBar(); return(Builds); }
static void CopyDLCToEXE(DLCItem item) { string sourcePath = Path.Combine(BaseConstMgr.Path_StreamingAssets, item.Name); string targetPath = Path.Combine(BuildConfig.DirPath, BuildConfig.FullName + "_Data/StreamingAssets", item.Name); BaseFileUtils.CopyDir(sourcePath, targetPath); }
public static void BuildBundle(DLCItem dlc) { OnPreBuild(); _BuildBundle(dlc); CopyDLCToEXE(dlc); OnPostBuild(); }
public static void BuildBundleAndEXE(DLCItem dlc) { OnPreBuild(); _BuildBundle(dlc); _BuildEXE(); OnPostBuild(); }
public static void BuildDLCConfig(DLCItem dlc) { //清除缓存 PackedAssets_Internal.Clear(); PackedAssets_Native.Clear(); PackedAssets_DLC.Clear(); Builds.Clear(); Rules.Clear(); AllDependencies.Clear(); AllAssets.Clear(); AllBundles.Clear(); AllSharedBundles.Clear(); Consts.Clear(); //永远提前打包Internal if (!dlc.IsInternal) { BuildDLCConfigInternal(Internal); } //如果不是NativeDLC则先BuildNativeDLC,防止资源被其他DLC重复打包 if (!dlc.IsInternal && !dlc.IsNative) { BuildDLCConfigInternal(Native); } BuildDLCConfigInternal(dlc); }
public override void OnInited() { if (Application.isEditor) { //复制路径 CopyDirectory.Clear(); CopyDirectory.Add("Language"); CopyDirectory.Add("Lua"); CopyDirectory.Add("Config"); //初始化默认DLC string internalRootPath = BaseConstMgr.Path_InternalBundle; Native = new DLCItem(); Native.Name = "Native"; Native.AddBuildData("Audio", BuildRuleType.Directroy, internalRootPath); Native.AddBuildData("Icon", BuildRuleType.Directroy, internalRootPath); Native.AddBuildData("Material", BuildRuleType.Directroy, internalRootPath); Native.AddBuildData("Prefab", BuildRuleType.Directroy, internalRootPath); Native.AddBuildData("System", BuildRuleType.Directroy, internalRootPath); Native.AddBuildData("UI", BuildRuleType.Directroy, internalRootPath); Native.LoadConfig(Data, CopyDirectory); //初始化扩展DLC DLCItems = new Dictionary <string, DLCItem>(); foreach (var item in DLC) { DLCItems.Add(item.Name, item); item.LoadConfig(Data, CopyDirectory); } } }
static void BuildManifestInternel(DLCItem dlcItem) { var builds = AssetBundleBuildsCache = BuildBuildRules(dlcItem); string dlcName = dlcItem.Name; string manifestPath = DLCAssetMgr.GetDLCManifestPath(dlcName); string dlcItemPath = DLCAssetMgr.GetDLCItemPath(dlcName); List <string> bundles = new List <string>(); List <string> assets = new List <string>(); if (builds.Count > 0) { foreach (var item in builds) { bundles.Add(item.assetBundleName); foreach (var assetPath in item.assetNames) { assets.Add(assetPath + ":" + (bundles.Count - 1)); } } } #region 创建Manifest文件 if (File.Exists(manifestPath)) { File.Delete(manifestPath); } DLCManifest dlcManifest = new DLCManifest(); foreach (var item in builds) { BundleData tempData = new BundleData(); tempData.DLCName = dlcItem.Name; tempData.BundleName = item.assetBundleName; foreach (var asset in item.assetNames) { AssetPathData pathData = new AssetPathData(); pathData.FullPath = asset; pathData.FileName = Path.GetFileNameWithoutExtension(asset); if (AllAssets.ContainsKey(asset)) { pathData.SourceBundleName = AllAssets[asset]; } tempData.AssetFullPaths.Add(pathData); } dlcManifest.Data.Add(tempData); } BaseFileUtils.SaveJson(manifestPath, dlcManifest, true); #endregion #region dlcitem if (File.Exists(dlcItemPath)) { File.Delete(dlcItemPath); } BaseFileUtils.SaveJson(dlcItemPath, dlcItem, true); #endregion CLog.Debug("[BuildScript] BuildManifest with " + assets.Count + " assets and " + bundles.Count + " bundels."); }
public static void BuildManifest(DLCItem dlc) { //如果不是NativeDLC则先BuildNativeDLC,防止资源被其他DLC重复打包 if (!dlc.IsNative) { BuildManifestInternel(Native); } BuildManifestInternel(dlc); }
private static void _BuildBundle(DLCItem dlcItem) { BaseFileUtils.EnsureDirectory(dlcItem.TargetPath); BuildManifest(dlcItem); BuildPipeline.BuildAssetBundles(dlcItem.TargetPath, AssetBundleBuildsCache.ToArray(), BuildAssetBundleOptions.ChunkBasedCompression | BuildAssetBundleOptions.ForceRebuildAssetBundle, EditorUserBuildSettings.activeBuildTarget); dlcItem.CopyAllFiles(); AssetDatabase.Refresh(); }
public static Bundle LoadBundle(string bundleName, string dlc, bool asyncRequest = false) { if (bundleName.IsInvStr() || dlc.IsInvStr()) { return(null); } //如果bundleName == dlc 表示LoadingAssetBundleManifest bool isLoadingAssetBundleManifest = bundleName == dlc; //是否为预加载Bundle bool isPreload = bundleName == BaseConstMgr.BN_Shader || bundleName == BaseConstMgr.BN_Shared; var url = Path.Combine(BaseConstMgr.Path_StreamingAssets, dlc) + "/" + bundleName; Bundle bundle = null; if (Bundles.ContainsKey(bundleName)) { bundle = Bundles[bundleName]; } else { if (asyncRequest) { bundle = new BundleAsync(url); } else { bundle = new Bundle(url); } bundle.name = bundleName; Bundles.Add(bundleName, bundle); bundle.Load(); //加载依赖的的Bundle if (!isLoadingAssetBundleManifest && !isPreload) { DLCItem dlcItem = GetDLCItem(dlc); var dependencies = dlcItem.GetAllDependencies(bundleName); if (dependencies != null && dependencies.Length > 0) { foreach (var item in dependencies) { var dependencieBundle = LoadBundle(item, dlc, asyncRequest); bundle.dependencies.Add(dependencieBundle); } } } } bundle.Retain(); return(bundle); }
public static T LoadRawAsset <T>(string bundleName, string assetName, DLCItem dlc) where T : UnityEngine.Object { string fullAssetsName = bundleName + assetName + dlc.Name; if (RawAssets.ContainsKey(fullAssetsName)) { return(RawAssets[fullAssetsName] as T); } var bundle = LoadRawBundle(bundleName, dlc); if (bundle != null) { var obj = bundle.LoadAsset <T>(assetName); if (obj != null) { RawAssets.Add(fullAssetsName, obj); } return(obj); } return(default);
public static AssetBundle LoadRawBundle(string name, DLCItem dlc) { string fullName = dlc.Name + name; if (RawBundles.ContainsKey(fullName)) { return(RawBundles[fullName]); } string path = Path.Combine(Application.streamingAssetsPath, dlc.Name) + "/" + dlc.Name.ToLower() + "_" + name; AssetBundle bundle = null; #if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN if (File.Exists(path)) #endif bundle = AssetBundle.LoadFromFile(path); if (bundle != null) { RawBundles.Add(fullName, bundle); } return(bundle); }
/// <summary> /// 加载DLC /// </summary> /// <param name="config"></param> public static bool LoadDLC(string name) { //屏蔽NoBundle下得目录 if (name == BaseConstMgr.Dir_NoBundles) { return(false); } if (DLCItems.ContainsKey(name)) { CLog.Error("重复加载!!!!"); return(false); } //DLC名称 string dlcName = name; //AB清单 AssetBundleManifest abManifest = null; //加载dlc item DLCItem dlcItem = BaseFileUtils.LoadJson <DLCItem>(GetDLCItemPath(dlcName)); //加载自定义Manifest DLCManifest dlcManifest = BaseFileUtils.LoadJson <DLCManifest>(GetDLCManifestPath(dlcName)); //bundle模式 if (!DLCConfig.Ins.IsEditorMode) { //加载Unity Assetbundle Manifest Bundle tempBundle = LoadBundle(dlcName, dlcName, false); abManifest = tempBundle.LoadAsset <AssetBundleManifest>(BaseConstMgr.STR_ABManifest); //如果是Native DLC 直接加载共享Shader和Shared包 if (dlcItem.IsNative) { LoadBundle(BaseConstMgr.BN_Shared, dlcName); LoadBundle(BaseConstMgr.BN_Shader, dlcName); } } DLCItems.Add(dlcItem.Name, dlcItem); dlcItem.Load(abManifest); LoadDLCManifest(dlcManifest); return(true); }
private static void _BuildBundle(DLCItem dlcItem) { FileUtil.EnsureDirectory(dlcItem.TargetPath); BuildDLCConfig(dlcItem); BuildAssetBundleOptions op = BuildAssetBundleOptions.None; if (DLCConfig.IsCompresse) { op |= BuildAssetBundleOptions.ChunkBasedCompression; } else { op |= BuildAssetBundleOptions.UncompressedAssetBundle; } if (DLCConfig.IsForceBuild) { op |= BuildAssetBundleOptions.ForceRebuildAssetBundle; } BuildPipeline.BuildAssetBundles(dlcItem.TargetPath, AssetBundleBuildsCache.ToArray(), op, EditorUserBuildSettings.activeBuildTarget); dlcItem.OnPostBuildBundle(); AssetDatabase.Refresh(); }
// 根据文件夹获得名称 static Tuple <string, string> GetABNameDirectory(DLCItem item, BuildRuleConfig data) { string source = data.Name.ToLower(); return(new Tuple <string, string>((item.Name + "_" + source).ToLower(), source.ToLower())); }
// 获得共享资源名称 static Tuple <string, string> GetABNameSharedDiscrete(DLCItem item, string path) { return(new Tuple <string, string>((item.Name + "_" + Const.BN_Shared.ToLower() + "/" + FileUtil.MD5(path)).ToLower(), Const.BN_Shared.ToLower())); //return new Tuple<string, string>((item.Name + "_" + Const.BN_Shared.ToLower() + "/" + path).ToLower(), Const.BN_Shared.ToLower()); }
static Tuple <string, string> GetABNameShared(DLCItem item) { return(new Tuple <string, string>(item.Name + "_" + Const.BN_Shared.ToLower(), Const.BN_Shared.ToLower())); }
static void BuildDLCConfigInternal(DLCItem dlcItem) { var builds = AssetBundleBuildsCache = GenerateAssetBundleBuildData(dlcItem); string constPath = dlcItem.GetConst(); string manifestPath = dlcItem.GetManifest(); string dlcItemPath = dlcItem.GetConfig(); List <string> bundles = new List <string>(); List <string> assets = new List <string>(); if (builds.Count > 0) { foreach (var item in builds) { bundles.Add(item.assetBundleName); foreach (var assetPath in item.assetNames) { assets.Add(assetPath + ":" + (bundles.Count - 1)); } } } #region 创建Manifest文件 if (File.Exists(manifestPath)) { File.Delete(manifestPath); } DLCManifest dlcManifest = new DLCManifest(); foreach (var item in builds) { BundleData tempData = new BundleData(); tempData.DLCName = dlcItem.Name; if (AllBundles.ContainsKey(item.assetBundleName)) { tempData.BundleName = item.assetBundleName; if (AllSharedBundles.Contains(item.assetBundleName)) { tempData.IsShared = true; } } else { CLog.Error("没有包含:" + item.assetBundleName); } foreach (var asset in item.assetNames) { AssetPathData pathData = new AssetPathData(); pathData.FullPath = asset; pathData.FileName = Path.GetFileNameWithoutExtension(asset); if (AllAssets.ContainsKey(asset)) { pathData.SourceBundleName = AllAssets[asset]; } tempData.AssetFullPaths.Add(pathData); } dlcManifest.Data.Add(tempData); } FileUtil.SaveJson(manifestPath, dlcManifest, true); #endregion #region dlcitem if (File.Exists(dlcItemPath)) { File.Delete(dlcItemPath); } FileUtil.SaveJson(dlcItemPath, dlcItem.Config, true); #endregion #region const if (File.Exists(constPath)) { File.Delete(constPath); } var cultureInfo = new System.Globalization.CultureInfo("en-us"); var w = new CodegenTextWriter(constPath, System.Text.Encoding.UTF8); w.WithCurlyBraces("namespace CYM", () => { w.WithCurlyBraces("public partial class Const", () => { foreach (var bundleData in dlcManifest.Data) { string newBundleName = ""; foreach (var pathData in bundleData.AssetFullPaths) { if (pathData.SourceBundleName.IsInv()) { continue; } //跳过指定的Bundle资源 if (pathData.SourceBundleName == Const.BN_System || pathData.SourceBundleName == Const.BN_Shared) { continue; } //获得相应的Bundle名称 if (pathData.SourceBundleName.StartsWith(Const.BN_Scene)) { newBundleName = Const.BN_Scene; } else { newBundleName = pathData.SourceBundleName; } //保证变量名称有效 var fileName = pathData.FileName.Replace(".", "_").Replace("(", "_").Replace(")", "").Trim(); //加上前缀 fileName = newBundleName.ToUpper() + "_" + fileName; //忽略不需要的Const if (DLCConfig.IsInIgnoreConst(fileName)) { continue; } if (Consts.Contains(fileName)) { continue; } Consts.Add(fileName); w.WriteLine($"public const string {fileName} = \"{pathData.FileName}\";"); } } }); }); w.Flush(); w.Dispose(); #endregion CLog.Info("[Builder][{0}] BuildManifest with " + assets.Count + " assets and " + bundles.Count + " bundels.", dlcItem.Name); }
/// <summary> /// 打包共享的资源 /// </summary> protected static void BuildSharedAssets(DLCItem dlcItem) { Dictionary <string, List <string> > bundles = new Dictionary <string, List <string> >(); foreach (var item in AllDependencies) { var name = "None"; var assetPath = item.Key; if (!assetPath.EndsWith(".cs", StringComparison.CurrentCulture) && !assetPath.EndsWith(".js", StringComparison.CurrentCulture)) { if (IsContainInPackedAssets(assetPath)) { continue; } //打包共享的Sahder资源,制作成一个完整的单独包 if (assetPath.EndsWith(".shader", StringComparison.CurrentCulture)) { name = BaseConstMgr.BN_Shader; } else { //如果依赖的资源小于2个,则跳过 if (item.Value.Count <= 1) { continue; } //打包Native共享资源 if (dlcItem.IsNative) { name = BaseConstMgr.BN_Shared; } //打包其他DLC资源,打成散包 else { name = BaseConstMgr.BN_Shared + "/" + GetABNameWithFullPath(Path.GetDirectoryName(assetPath)); } } //添加到Bundles List <string> list = null; if (!bundles.TryGetValue(name, out list)) { list = new List <string>(); bundles.Add(name, list); } if (!list.Contains(assetPath)) { list.Add(assetPath); AddToPackedAssets(assetPath); } } } //放入打包容器 foreach (var item in bundles) { AssetBundleBuild build = new AssetBundleBuild(); build.assetBundleName = item.Key;// + "_" + item.Value.Count; build.assetNames = item.Value.ToArray(); Builds.Add(build); } }
/// <summary> /// 打包共享的资源 /// </summary> protected static void BuildSharedAssets(DLCItem dlc) { //打散包的时候需要用到 Dictionary <string, List <string> > dicAssets = new Dictionary <string, List <string> >(); List <string> assets = new List <string>(); foreach (var item in AllDependencies) { var assetPath = item.Key; if (!assetPath.EndsWith(".cs", StringComparison.CurrentCulture) && !assetPath.EndsWith(".js", StringComparison.CurrentCulture)) { //bundle里的资源不包含到共享包 if (assetPath.Contains(SysConst.Dir_Bundles)) { continue; } if (IsContainInPackedAssets(assetPath)) { continue; } //如果依赖的资源小于2个,则跳过 if (item.Value.Count <= 1) { continue; } string dirPath = Path.GetDirectoryName(assetPath); if (!dicAssets.ContainsKey(dirPath)) { dicAssets.Add(dirPath, new List <string>()); } dicAssets[dirPath].Add(assetPath); assets.Add(assetPath); AddToPackedAssets(assetPath); } } if (dicAssets.Count > 0 && assets.Count > 0) { //离散共享包 if (DLCConfig.IsDiscreteShared) { foreach (var item in dicAssets) { Tuple <string, string> bundleName = GetABNameSharedDiscrete(dlc, item.Key); AssetBundleBuild build = new AssetBundleBuild(); build.assetBundleName = bundleName.Item1; build.assetNames = item.Value.ToArray(); Builds.Add(build); AddToAllBundles(bundleName, true); } } //非离散共享包 else { Tuple <string, string> bundleName = GetABNameShared(dlc); AssetBundleBuild build = new AssetBundleBuild(); build.assetBundleName = bundleName.Item1; build.assetNames = assets.ToArray(); Builds.Add(build); AddToAllBundles(bundleName, true); } } }
public BuildAssetsWithPath(DLCItem dlc, BuildRuleConfig config) : base(dlc, config) { }
public BuildAssetsWithDirectroy(DLCItem dlc, BuildRuleConfig config) : base(dlc, config) { }
public BuildRule(DLCItem dlc, BuildRuleConfig config) { DLCItem = dlc; Config = config; }
// 根据文件夹以及文件名生成Bundle名称 static Tuple <string, string> GetABNameFile(DLCItem item, BuildRuleConfig data, string filePath) { string source = (data.Name + "/" + Path.GetFileNameWithoutExtension(filePath)).ToLower(); return(new Tuple <string, string>((item.Name + "_" + source).ToLower(), source.ToLower())); }
static void CopyDLCToEXE(DLCItem item) { }
/// <summary> /// 加载DLC /// </summary> /// <param name="config"></param> public static bool LoadDLC(DLCItemConfig config) { if (LoadedDLCItems.ContainsKey(config.Name)) { CLog.Error("重复加载!!!!"); return(false); } //DLC名称 string dlcName = config.Name; //AB清单 AssetBundleManifest abManifest = LoadAssetBundleManifest(dlcName); //if (!DLCConfig.Ins.IsEditorMode) //{ //加载Shared包 //if(DLCConfig.IsInitLoadSharedBundle) // LoadAllSharedBundle(dlcName); //} DLCItem item = new DLCItem(config, abManifest); //加载自定义Manifest LoadManifest(item); LoadedDLCItems.Add(dlcName, item); CLog.Info("[DLC] Load dlc:{0} succeed", dlcName); return(true); void LoadManifest(DLCItem dlc) { DLCManifest reader = dlc.GetManifestFile(); if (reader == null) { CLog.Error("错误:reader 为 null"); return; } foreach (var bundleDataItem in reader.Data) { string bundle = bundleDataItem.BundleName; allBundles.Add(bundle); if (!bmap.ContainsKey(bundle)) { bmap.Add(bundle, new List <int>()); } if (bundleDataItem.IsShared) { if (!allSharedBundles.ContainsKey(dlc.Name)) { allSharedBundles.Add(dlc.Name, new List <string>()); } allSharedBundles[dlc.Name].Add(bundle); } foreach (var assetPathData in bundleDataItem.AssetFullPaths) { //完整路径 string fullpath = assetPathData.FullPath; //添加完整路径到资源表 allAssets.Add(fullpath); //计算资源路径Index int assetPathIndex = allAssets.Count - 1; //计算资源bunleIndex int bundleNameIndex = allBundles.Count - 1; //添加完整资源路径的Index到映射表中 bmap[bundle].Add(assetPathIndex); //添加完整的Bundle名称的Index到映射表中 amap[fullpath] = bundleNameIndex; //如果资源有自己的Bundle设定,则添加到映射表中 if (!assetPathData.SourceBundleName.IsInv()) { string bampKey = assetPathData.SourceBundleName + assetPathData.FileName; bamap[bampKey] = new Tuple <int, string>(assetPathIndex, bundleDataItem.DLCName); allBundlesAssetsMap.Add(bampKey); } } } } }
//刷新DLC public void RefreshDLC() { Config.Clear(); AllDirectory.Clear(); CopyDirectory.Clear(); IgnoreConstSet.Clear(); ConfigExtend.Clear(); ConfigAll.Clear(); EditorExtend.Clear(); EditorAll.Clear(); foreach (var item in BuildRule) { AddBuildConfig(item); } foreach (var item in IgnoreConst) { AddIgnoreConst(item); } //加载内部dlc ConfigInternal = new DLCItemConfig(Const.STR_InternalDLC); EditorInternal = new DLCItem(ConfigInternal); //加载原生dlc ConfigNative = new DLCItemConfig(Const.STR_NativeDLC); EditorNative = new DLCItem(ConfigNative); //加载其他额外DLC foreach (var item in DLC) { var dlcItem = new DLCItemConfig(item.Name); ConfigExtend.Add(dlcItem); EditorExtend.Add(new DLCItem(dlcItem)); } ConfigAll = new List <DLCItemConfig>(ConfigExtend); ConfigAll.Add(ConfigInternal); ConfigAll.Add(ConfigNative); EditorAll = new List <DLCItem>(EditorExtend); EditorAll.Add(EditorInternal); EditorAll.Add(EditorNative); #if UNITY_EDITOR if (!Application.isPlaying) { foreach (var item in AllDirectory) { FileUtil.EnsureDirectory(Path.Combine(Const.Path_NativeDLC, item)); } foreach (var item in DLC) { foreach (var dic in AllDirectory) { FileUtil.EnsureDirectory(Path.Combine(Const.Path_Bundles, item.Name, dic)); } } } #endif }
/// <summary> /// ex. native_prefab,必须加native_前缀,因为需要加载到全局的Manifest,防止dlc之间的重复 /// <returns></returns> // 返回完整的路径作为Bundle名称 static Tuple <string, string> GetABNamePath(DLCItem item, string filePath) { string source = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)).Replace('\\', '/'); return(new Tuple <string, string>((item.Name + "_" + source).ToLower(), source.ToLower())); }