diff --git a/BundleMasterRuntime/AssetComponentCheck.cs b/BundleMasterRuntime/AssetComponentCheck.cs new file mode 100644 index 0000000..598e609 --- /dev/null +++ b/BundleMasterRuntime/AssetComponentCheck.cs @@ -0,0 +1,45 @@ +using System.IO; +using UnityEditor; +using UnityEngine; + +namespace BM +{ + public static partial class AssetComponent + { + /// + /// 判定一个资源是否存在,如果这个资源是组里的资源,那么只能检测到这个资源所在的组是否存在 + /// + public static bool CheckAssetExist(string assetPath, string bundlePackageName = null) + { + if (bundlePackageName == null) + { + bundlePackageName = AssetComponentConfig.DefaultBundlePackageName; + } + if (AssetComponentConfig.AssetLoadMode == AssetLoadMode.Develop) + { +#if UNITY_EDITOR + assetPath = Path.Combine(Application.dataPath + "/../", assetPath); + return File.Exists(assetPath); +#else + AssetLogHelper.LogError("检查资源: " + assetPath + " 失败(资源检查Develop模式只能在编辑器下运行)"); + return false; +#endif + } + if (!BundleNameToRuntimeInfo.TryGetValue(bundlePackageName, out BundleRuntimeInfo bundleRuntimeInfo)) + { + AssetLogHelper.LogError(bundlePackageName + "检查资源时分包没有初始化"); + return false; + } + string groupPath = GroupAssetHelper.IsGroupAsset(assetPath, bundleRuntimeInfo.LoadGroupDicKey); + if (groupPath != null) + { + return true; + } + if (bundleRuntimeInfo.LoadFileDic.ContainsKey(assetPath)) + { + return true; + } + return false; + } + } +} \ No newline at end of file diff --git a/BundleMasterRuntime/AssetComponentInit.cs b/BundleMasterRuntime/AssetComponentInit.cs index 2d6bfa8..cde19ce 100644 --- a/BundleMasterRuntime/AssetComponentInit.cs +++ b/BundleMasterRuntime/AssetComponentInit.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Text.RegularExpressions; using UnityEngine; using ET; @@ -32,7 +33,7 @@ public static async ETTask Initialize(string bundlePackageName, string sec BundleNameToRuntimeInfo.Add(bundlePackageName, bundleRuntimeInfo); ETTask fileTcs= ETTask.Create(); - string filePath = BundleFileExistPath(bundlePackageName, "FileLogs.txt"); + string filePath = BundleFileExistPath(bundlePackageName, "FileLogs.txt", true); using (UnityWebRequest webRequest = UnityWebRequest.Get(filePath)) { UnityWebRequestAsyncOperation weq = webRequest.SendWebRequest(); @@ -47,7 +48,7 @@ public static async ETTask Initialize(string bundlePackageName, string sec if (!string.IsNullOrEmpty(webRequest.error)) #endif { - AssetLogHelper.LogError("初始化分包未找到FileLogs 分包名: " + bundlePackageName); + AssetLogHelper.LogError("初始化分包未找到FileLogs 分包名: " + bundlePackageName + "\t" + filePath); return false; } string fileLogs = webRequest.downloadHandler.text; @@ -74,7 +75,7 @@ public static async ETTask Initialize(string bundlePackageName, string sec } } ETTask dependTcs = ETTask.Create(); - string dependPath = BundleFileExistPath(bundlePackageName, "DependLogs.txt"); + string dependPath = BundleFileExistPath(bundlePackageName, "DependLogs.txt", true); using (UnityWebRequest webRequest = UnityWebRequest.Get(dependPath)) { UnityWebRequestAsyncOperation weq = webRequest.SendWebRequest(); @@ -89,7 +90,7 @@ public static async ETTask Initialize(string bundlePackageName, string sec if (!string.IsNullOrEmpty(webRequest.error)) #endif { - AssetLogHelper.LogError("初始化分包未找到DependLogs 分包名: " + bundlePackageName); + AssetLogHelper.LogError("初始化分包未找到DependLogs 分包名: " + bundlePackageName + "\t" + dependPath); return false; } string dependLogs = webRequest.downloadHandler.text; @@ -105,7 +106,7 @@ public static async ETTask Initialize(string bundlePackageName, string sec } } ETTask groupTcs = ETTask.Create(); - string groupPath = BundleFileExistPath(bundlePackageName, "GroupLogs.txt"); + string groupPath = BundleFileExistPath(bundlePackageName, "GroupLogs.txt", true); using (UnityWebRequest webRequest = UnityWebRequest.Get(groupPath)) { UnityWebRequestAsyncOperation weq = webRequest.SendWebRequest(); @@ -120,7 +121,7 @@ public static async ETTask Initialize(string bundlePackageName, string sec if (!string.IsNullOrEmpty(webRequest.error)) #endif { - AssetLogHelper.LogError("初始化分包未找到GroupLogs 分包名: " + bundlePackageName); + AssetLogHelper.LogError("初始化分包未找到GroupLogs 分包名: " + bundlePackageName+ "\t" + groupPath); return false; } string groupLogs = webRequest.downloadHandler.text; @@ -154,28 +155,40 @@ public static async ETTask Initialize(string bundlePackageName, string sec private static async ETTask LoadShader(string bundlePackageName) { ETTask tcs = ETTask.Create(); - string shaderPath = BundleFileExistPath(bundlePackageName, "shader_" + bundlePackageName.ToLower()); - byte[] shaderData; + string shaderPath = BundleFileExistPath(bundlePackageName, "shader_" + bundlePackageName.ToLower(), true); if (BundleNameToRuntimeInfo[bundlePackageName].Encrypt) { - shaderData = await VerifyHelper.GetDecryptDataAsync(shaderPath, null, BundleNameToRuntimeInfo[bundlePackageName].SecretKey); - } - else - { - shaderData = await VerifyHelper.GetDecryptDataAsync(shaderPath); - } - if (shaderData == null) - { - tcs.SetResult(); + byte[] shaderData = await VerifyHelper.GetDecryptDataAsync(shaderPath, null, BundleNameToRuntimeInfo[bundlePackageName].SecretKey); + if (shaderData == null) + { + tcs.SetResult(); + } + else + { + AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(shaderData); + request.completed += operation => + { + BundleNameToRuntimeInfo[bundlePackageName].Shader = request.assetBundle; + tcs.SetResult(); + }; + } } else { - AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(shaderData); - request.completed += operation => + byte[] shaderData = await VerifyHelper.GetDecryptDataAsync(shaderPath, null, BundleNameToRuntimeInfo[bundlePackageName].SecretKey); + if (shaderData == null) { - BundleNameToRuntimeInfo[bundlePackageName].Shader = request.assetBundle; tcs.SetResult(); - }; + } + else + { + AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(BundleFileExistPath(bundlePackageName, "shader_" + bundlePackageName.ToLower(), false)); + request.completed += operation => + { + BundleNameToRuntimeInfo[bundlePackageName].Shader = request.assetBundle; + tcs.SetResult(); + }; + } } await tcs; } diff --git a/BundleMasterRuntime/AssetComponentTools.cs b/BundleMasterRuntime/AssetComponentTools.cs index d3648e2..e8b8da7 100644 --- a/BundleMasterRuntime/AssetComponentTools.cs +++ b/BundleMasterRuntime/AssetComponentTools.cs @@ -11,30 +11,63 @@ public static partial class AssetComponent /// /// 获取Bundle信息文件的路径 /// - internal static string BundleFileExistPath(string bundlePackageName, string fileName) + internal static string BundleFileExistPath(string bundlePackageName, string fileName, bool isWebLoad) { - if (AssetComponentConfig.AssetLoadMode == AssetLoadMode.Local) + string path = GetBasePath(bundlePackageName, fileName); + if (isWebLoad) { - string path = Path.Combine(AssetComponentConfig.LocalBundlePath, bundlePackageName, fileName); -#if UNITY_IOS || UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX + //通过webReq加载 +#if UNITY_ANDROID && !UNITY_EDITOR + if (!path.Contains("file:///")) + { + path = "file://" + path; + } +#elif UNITY_IOS && !UNITY_EDITOR + path = "file://" + path; +#elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX path = "file://" + path; +#elif UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN +#else #endif return path; } else { - string path = Path.Combine(AssetComponentConfig.HotfixPath, bundlePackageName, fileName); - if (!File.Exists(path)) + //直接加载 +#if UNITY_ANDROID && !UNITY_EDITOR + if (!path.Contains("file:///")) { - path = Path.Combine(AssetComponentConfig.LocalBundlePath, bundlePackageName, fileName); -#if UNITY_IOS || UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX path = "file://" + path; -#endif } - else +#elif UNITY_IOS && !UNITY_EDITOR +#elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX + +#elif UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN +#else +#endif + return path; + } + } + + /// + /// 得到基础的路径 + /// + private static string GetBasePath(string bundlePackageName, string fileName) + { + if (AssetComponentConfig.AssetLoadMode == AssetLoadMode.Local) + { + string path = Path.Combine(AssetComponentConfig.LocalBundlePath, bundlePackageName, fileName); + return path; + } + else + { + string path = Path.Combine(AssetComponentConfig.HotfixPath, bundlePackageName, fileName); + if (!File.Exists(path)) { - path = "file://" + path; + //热更目录不存在,返回streaming目录 + path = Path.Combine(AssetComponentConfig.LocalBundlePath, bundlePackageName, fileName); } + //热更目录存在,返回热更目录 return path; } } diff --git a/BundleMasterRuntime/AssetComponentUpdate.cs b/BundleMasterRuntime/AssetComponentUpdate.cs index 993ae51..ed4dfe2 100644 --- a/BundleMasterRuntime/AssetComponentUpdate.cs +++ b/BundleMasterRuntime/AssetComponentUpdate.cs @@ -95,7 +95,7 @@ public static async ETTask CheckAllBundlePackageUpdate(Dic crcStream.AutoFlush = false; updateBundleDataInfo.PackageCRCFile.Add(bundlePackageName, crcStream); //获取本地的VersionLog - string localVersionLogExistPath = BundleFileExistPath(bundlePackageName, "VersionLogs.txt"); + string localVersionLogExistPath = BundleFileExistPath(bundlePackageName, "VersionLogs.txt", true); ETTask logTcs = ETTask.Create(); string localVersionLog; using (UnityWebRequest webRequest = UnityWebRequest.Get(localVersionLogExistPath)) @@ -361,7 +361,7 @@ private static async ETTask CheckFileCRC(string remoteVersionDataLine, string bu { string[] info = remoteVersionDataLine.Split('|'); //如果文件不存在直接加入更新 - string filePath = BundleFileExistPath(bundlePackageName, info[0]); + string filePath = BundleFileExistPath(bundlePackageName, info[0], true); uint fileCRC32 = await VerifyHelper.GetFileCRC32(filePath); //判断是否和远程一样, 不一样直接加入更新 if (uint.Parse(info[2]) != fileCRC32) diff --git a/BundleMasterRuntime/Base/LoadBaseRuntimeLoad.cs b/BundleMasterRuntime/Base/LoadBaseRuntimeLoad.cs index 664490b..c91043a 100644 --- a/BundleMasterRuntime/Base/LoadBaseRuntimeLoad.cs +++ b/BundleMasterRuntime/Base/LoadBaseRuntimeLoad.cs @@ -82,17 +82,18 @@ internal void LoadAssetBundle(string bundlePackageName) return; } } - string assetBundlePath = AssetComponent.BundleFileExistPath(bundlePackageName, AssetBundleName); - byte[] data; + if (AssetComponent.BundleNameToRuntimeInfo[bundlePackageName].Encrypt) { - data = VerifyHelper.GetDecryptData(assetBundlePath, AssetComponent.BundleNameToRuntimeInfo[bundlePackageName].SecretKey); + string assetBundlePath = AssetComponent.BundleFileExistPath(bundlePackageName, AssetBundleName, true); + byte[] data = VerifyHelper.GetDecryptData(assetBundlePath, AssetComponent.BundleNameToRuntimeInfo[bundlePackageName].SecretKey); + AssetBundle = AssetBundle.LoadFromMemory(data); } else { - data = VerifyHelper.GetDecryptData(assetBundlePath); + string assetBundlePath = AssetComponent.BundleFileExistPath(bundlePackageName, AssetBundleName, false); + AssetBundle = AssetBundle.LoadFromFile(assetBundlePath); } - AssetBundle = AssetBundle.LoadFromMemory(data); _loadState = LoadState.Finish; for (int i = 0; i < _loadFinishTasks.Count; i++) { @@ -116,24 +117,25 @@ internal async ETTask LoadAssetBundleAsync(ETTask tcs, string bundlePackageName) } _loadFinishTasks.Add(tcs); _loadState = LoadState.Loading; - string assetBundlePath = AssetComponent.BundleFileExistPath(bundlePackageName, AssetBundleName); - byte[] data; + if (AssetComponent.BundleNameToRuntimeInfo[bundlePackageName].Encrypt) { - data = await VerifyHelper.GetDecryptDataAsync(assetBundlePath, _loadProgress, AssetComponent.BundleNameToRuntimeInfo[bundlePackageName].SecretKey); + string assetBundlePath = AssetComponent.BundleFileExistPath(bundlePackageName, AssetBundleName, true); + await LoadDataFinish(assetBundlePath, bundlePackageName); } else { - data = await VerifyHelper.GetDecryptDataAsync(assetBundlePath, _loadProgress); + string assetBundlePath = AssetComponent.BundleFileExistPath(bundlePackageName, AssetBundleName, false); + LoadBundleFinish(assetBundlePath); } - LoadDataFinish(data); } /// - /// Data加载完成后执行的 + /// 通过Byte加载完成(只有启用了异或加密才使用此加载方式) /// - private void LoadDataFinish(byte[] data) + private async ETTask LoadDataFinish(string assetBundlePath, string bundlePackageName) { + byte[] data = await VerifyHelper.GetDecryptDataAsync(assetBundlePath, _loadProgress, AssetComponent.BundleNameToRuntimeInfo[bundlePackageName].SecretKey); if (_loadState == LoadState.Finish) { return; @@ -156,6 +158,34 @@ private void LoadDataFinish(byte[] data) }; } + /// + /// 通过路径直接加载硬盘上的AssetBundle + /// + /// + private void LoadBundleFinish(string assetBundlePath) + { + if (_loadState == LoadState.Finish) + { + return; + } + _assetBundleCreateRequest = AssetBundle.LoadFromFileAsync(assetBundlePath); + _assetBundleCreateRequest.completed += operation => + { + AssetBundle = _assetBundleCreateRequest.assetBundle; + for (int i = 0; i < _loadFinishTasks.Count; i++) + { + _loadFinishTasks[i].SetResult(); + } + _loadFinishTasks.Clear(); + _loadState = LoadState.Finish; + //判断是否还需要 + if (_refCount <= 0) + { + AssetComponent.AddPreUnLoadPool(this); + } + }; + } + /// /// 强制加载完成 /// @@ -172,17 +202,18 @@ internal void ForceLoadFinish(string bundlePackageName) AssetBundle = _assetBundleCreateRequest.assetBundle; return; } - string assetBundlePath = AssetComponent.BundleFileExistPath(bundlePackageName, AssetBundleName); - byte[] data; + if (AssetComponent.BundleNameToRuntimeInfo[bundlePackageName].Encrypt) { - data = VerifyHelper.GetDecryptData(assetBundlePath, AssetComponent.BundleNameToRuntimeInfo[bundlePackageName].SecretKey); + string assetBundlePath = AssetComponent.BundleFileExistPath(bundlePackageName, AssetBundleName, true); + byte[] data = VerifyHelper.GetDecryptData(assetBundlePath, AssetComponent.BundleNameToRuntimeInfo[bundlePackageName].SecretKey); + AssetBundle = AssetBundle.LoadFromMemory(data); } else { - data = VerifyHelper.GetDecryptData(assetBundlePath); + string assetBundlePath = AssetComponent.BundleFileExistPath(bundlePackageName, AssetBundleName, false); + AssetBundle = AssetBundle.LoadFromFile(assetBundlePath); } - AssetBundle = AssetBundle.LoadFromMemory(data); for (int i = 0; i < _loadFinishTasks.Count; i++) { _loadFinishTasks[i].SetResult(); @@ -219,14 +250,20 @@ internal float GetProgress() { return 0; } - if (_assetBundleCreateRequest == null) + + if (_loadProgress.WeqOperation == null) { - return _loadProgress.GetWebProgress() / 2; + if (_assetBundleCreateRequest == null) + { + return _loadProgress.GetWebProgress() / 2; + } + return _assetBundleCreateRequest.progress; } - else + if (_assetBundleCreateRequest == null) { - return (_assetBundleCreateRequest.progress + 1.0f) / 2; + return _loadProgress.GetWebProgress() / 2; } + return (_assetBundleCreateRequest.progress + 1.0f) / 2; } } diff --git a/Editor/BundleMasterEditor/BuildAssets.cs b/Editor/BundleMasterEditor/BuildAssets.cs index 8c38c32..fdf6287 100644 --- a/Editor/BundleMasterEditor/BuildAssets.cs +++ b/Editor/BundleMasterEditor/BuildAssets.cs @@ -6,8 +6,10 @@ using System.Text.RegularExpressions; using UnityEngine; using UnityEditor; +using UnityEditor.U2D; using Debug = UnityEngine.Debug; using UnityEngine.Rendering; +using UnityEngine.U2D; namespace BM { @@ -56,6 +58,22 @@ public static void BuildAllBundle() } } } + //查找所有图集 + // Dictionary> textureToSpriteAtlas = new Dictionary>(); + // foreach (string guid in AssetDatabase.FindAssets($"t:{nameof(SpriteAtlas)}")) + // { + // string atlasPath = AssetDatabase.GUIDToAssetPath(guid); + // SpriteAtlas spriteAtlas = AssetDatabase.LoadAssetAtPath(atlasPath); + // Object[] sprites = spriteAtlas.GetPackables(); + // foreach (Object sprite in sprites) + // { + // string spritePath = AssetDatabase.GetAssetPath(sprite); + // Debug.LogError(spritePath); + // } + // + // + // } + //记录所有加载路径 HashSet allAssetLoadPath = new HashSet(); //构建所有分包