三国卡牌客户端基础资源仓库
yyl
8 天以前 0c5d95969a20c5b77adf54e568528b4e627eb472
打包资源bug跟export资源问题修复
2个文件已修改
167 ■■■■■ 已修改文件
Assets/Editor/Tool/ClientPackage.cs 84 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Editor/YooAsset/YooAssetBuildTool.cs 83 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Editor/Tool/ClientPackage.cs
@@ -8,6 +8,7 @@
using System.Text;
using Cysharp.Threading.Tasks;
using YooAsset.Editor;
using UnityEngine.AssetBundles;
//using Beebyte.Obfuscator;
@@ -142,15 +143,22 @@
        }
        Debug.Log("[ClientPackage] YooAsset 资源打包完成。");
        // 打包成功后,将完整 StreamingAssets/yoo 拷贝到 Output Path(裁剪前执行,确保拿到全量资源)
        if (!string.IsNullOrEmpty(_assetBundlePath))
        {
            YooAssetBuildTool.CopyStreamingAssetsToOutputPath(_assetBundlePath);
        }
        // YooAsset StreamingAssets 根目录
        string yooRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
        // ---- NullAsset(小包):只保留 Launch 必需 Package,其它资源从 CDN 按需下载 ----
        // ---- NullAsset(小包):不随包携带 StreamingAssets 资源,全部从 CDN 按需下载 ----
        if (smallPackages.Count > 0)
        {
            RemovePackagesExcept(yooRoot, LaunchRequiredYooPackages);
            YooAssetBuildTool.ClearStreamingAssetsYooDirectory();
            Debug.Log("[ClientPackage] NullAsset: 已清空 StreamingAssets/yoo");
            // 写入随包 Package 列表,运行时 Builtin/Dll 创建 BuildinFileSystem,其它包走 CacheFileSystem
            // 写入随包 Package 列表,NullAsset 为空列表
            YooAssetBuildTool.WriteBuildinPackageList();
            for (int i = 0; i < smallPackages.Count; i++)
@@ -219,6 +227,7 @@
    public static void BuildApk(string _sdkPath, string _output, string _publisher, int _buildIndex, bool _development, string _streamingAssetsOutputPath = null)
    {
        YooAssetBuildTool.DeleteStartupConfigsFromStreamingAssets();
        PreBuild(_publisher, _buildIndex);
        var auditTimeFile = StringUtility.Concat(Application.dataPath, Path.DirectorySeparatorChar.ToString(), "Resources/Config/AuditTime.txt");
        if (File.Exists(auditTimeFile))
@@ -359,12 +368,6 @@
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
        if (_streamingAssetsOutputPath != null && !YooAssetBuildTool.CopyStreamingAssetsToOutputPath(_streamingAssetsOutputPath))
        {
            Debug.LogError("[ClientPackage] 拷贝 StreamingAssets 到资源输出目录失败,中止 APK 构建。TARGET=" + _streamingAssetsOutputPath);
            return;
        }
        // 确保不以 Gradle 工程模式输出(HybridCLR StripAOT 步骤会临时置为 true,若未还原则会输出文件夹而非 APK)
        EditorUserBuildSettings.exportAsGoogleAndroidProject = false;
@@ -411,46 +414,42 @@
        string copySdkFile;
        copySdkFile = StringUtility.Concat(SDK_PLUGIN_PROJECT, "/Channel/Android/", versionConfig.sdkFileName, "/AndroidManifest.xml");
        File.Copy(copySdkFile, MANIFEST_PATH);
        PreBuild(_publisher, _buildIndex);
        PlayerSettings.Android.bundleVersionCode = VersionConfig.GetVersionNumber(versionConfig.version);
        PlayerSettings.enableInternalProfiler = _development;
        //完整取StreamingAssets 资源
        // // 先清理StreamingAssets,再根据assetAccess配置拷贝资源到StreamingAssets
        // var streamingPath = ResourcesPath.Instance.StreamingAssetPath;
        // if (Directory.Exists(streamingPath))
        //     Directory.Delete(streamingPath, true);
        // if (!string.IsNullOrEmpty(_assetBundlePath) && Directory.Exists(_assetBundlePath))
        // {
        //     switch (versionConfig.assetAccess)
        //     {
        //         case InstalledAsset.NullAsset:
        //             CopyNullAssetResources(_assetBundlePath, streamingPath);
        //             break;
        //         case InstalledAsset.HalfAsset:
        //             CopyHalfAssetResources(_assetBundlePath, streamingPath);
        //             break;
        //         case InstalledAsset.FullAsset:
        //         case InstalledAsset.IngoreDownLoad:
        //             CopyFullAssetResources(_assetBundlePath, streamingPath);
        //             break;
        //     }
        //     Debug.LogFormat("资源拷贝完成({0}),从 {1} 到 {2}", versionConfig.assetAccess, _assetBundlePath, streamingPath);
        // }
        // else
        // {
        //     Debug.LogWarningFormat("AssetBundle路径为空或不存在: {0},导出工程将不包含游戏资源", _assetBundlePath);
        // }
        if (_assetBundlePath != null && !YooAssetBuildTool.CopyStreamingAssetsToOutputPath(_assetBundlePath))
        if (!YooAssetBuildTool.BuildAllPackagesCore(incremental: false, _assetBundlePath))
        {
            Debug.LogError("[ClientPackage] 拷贝 StreamingAssets 到资源输出目录失败,中止 Android 工程导出。TARGET=" + _assetBundlePath);
            Debug.LogError("[ClientPackage] YooAsset 资源打包失败,中止 Android 工程导出。");
            return;
        }
        string yooRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
        switch (versionConfig.assetAccess)
        {
            case InstalledAsset.NullAsset:
                YooAssetBuildTool.ClearStreamingAssetsYooDirectory();
                Debug.Log("[ClientPackage] NullAsset Export: 已清空 StreamingAssets/yoo");
                break;
            case InstalledAsset.HalfAsset:
                var removePackages = new List<string> { "Battle", "Audio", "Video", "UIEffect" };
                if (!includeUI) removePackages.Add("UI");
                foreach (var pkgName in removePackages)
                {
                    string pkgDir = Path.Combine(yooRoot, pkgName);
                    if (Directory.Exists(pkgDir))
                    {
                        Directory.Delete(pkgDir, true);
                        Debug.Log($"[ClientPackage] HalfAsset Export: 已剔除 Package '{pkgName}'");
                    }
                }
                break;
        }
        YooAssetBuildTool.WriteBuildinPackageList();
        YooAssetBuildTool.DeleteStartupConfigsFromStreamingAssets();
        PreBuild(_publisher, _buildIndex);
        // 关键设置:导出为Gradle工程而非直接打APK
        EditorUserBuildSettings.exportAsGoogleAndroidProject = true;
@@ -475,6 +474,9 @@
        Debug.LogFormat("导出Android工程完成!输出路径: {0}", outputDir);
        // 恢复完整 StreamingAssets 供后续打包使用
        RestoreYooStreamingAssets();
        // 导出完成后恢复设置
        EditorUserBuildSettings.exportAsGoogleAndroidProject = false;
        EditorUserBuildSettings.development = false;
Assets/Editor/YooAsset/YooAssetBuildTool.cs
@@ -441,6 +441,8 @@
        Debug.Log($"[YooAssetBuildTool] 版本号: {version}");
        Debug.Log($"[YooAssetBuildTool] 平台: {EditorUserBuildSettings.activeBuildTarget}");
        ClearStreamingAssetsYooDirectory();
        for (int i = 0; i < ALL_PACKAGES.Length; i++)
        {
            string pkgName = ALL_PACKAGES[i];
@@ -493,8 +495,8 @@
            Debug.LogWarning("[YooAssetBuildTool] 补齐 StreamingAssets 启动配置失败,将继续拷贝现有 StreamingAssets。");
        }
        string sourceRoot = System.IO.Path.Combine(Application.dataPath, "StreamingAssets");
        string destRoot = ResolveOutputDirectory(outputPath);
        string sourceRoot = System.IO.Path.Combine(Application.dataPath, "StreamingAssets", "yoo");
        string destRoot = ResolveYooOutputDirectory(outputPath);
        if (!System.IO.Directory.Exists(sourceRoot))
        {
@@ -516,32 +518,29 @@
            return false;
        }
        if (System.IO.Directory.Exists(destFullPath))
        {
            System.IO.Directory.Delete(destFullPath, true);
        }
        System.IO.Directory.CreateDirectory(destFullPath);
        int copiedCount = 0;
        foreach (var sourceFile in System.IO.Directory.GetFiles(sourceFullPath, "*", System.IO.SearchOption.AllDirectories))
        foreach (var packageName in ALL_PACKAGES)
        {
            if (string.Equals(System.IO.Path.GetExtension(sourceFile), ".meta", StringComparison.OrdinalIgnoreCase))
            string sourcePackageDir = System.IO.Path.Combine(sourceFullPath, packageName);
            if (!System.IO.Directory.Exists(sourcePackageDir))
            {
                continue;
            }
            string relativePath = sourceFile.Substring(sourceFullPath.Length).TrimStart('\\', '/');
            string destFile = System.IO.Path.Combine(destFullPath, relativePath);
            string destDir = System.IO.Path.GetDirectoryName(destFile);
            if (!System.IO.Directory.Exists(destDir))
            {
                System.IO.Directory.CreateDirectory(destDir);
            }
            System.IO.File.Copy(sourceFile, destFile, true);
            copiedCount++;
            copiedCount += CopyDirectoryFiles(sourcePackageDir, System.IO.Path.Combine(destFullPath, packageName));
        }
        bool configCopied = false;
        try
        {
            configCopied = CopyStartupConfigsToYooDirectory(System.IO.Path.Combine(destFullPath, "yoo"));
            configCopied = CopyStartupConfigsToYooDirectory(destFullPath);
        }
        catch (Exception ex)
        {
@@ -550,11 +549,22 @@
        if (!configCopied)
        {
            Debug.LogWarning($"[YooAssetBuildTool] 补齐输出目录启动配置失败,请检查输出目录: {System.IO.Path.Combine(destFullPath, "yoo")}");
            Debug.LogWarning($"[YooAssetBuildTool] 补齐输出目录启动配置失败,请检查输出目录: {destFullPath}");
        }
        Debug.Log($"[YooAssetBuildTool] 已拷贝 StreamingAssets 到输出目录: {copiedCount} 个文件,from={sourceFullPath}, to={destFullPath}");
        return true;
    }
    public static void ClearStreamingAssetsYooDirectory()
    {
        string yooRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
        if (System.IO.Directory.Exists(yooRoot))
        {
            System.IO.Directory.Delete(yooRoot, true);
        }
        System.IO.Directory.CreateDirectory(yooRoot);
    }
    private static string ResolveOutputDirectory(string outputPath)
@@ -574,9 +584,49 @@
        return System.IO.Path.GetFullPath(System.IO.Path.Combine(projectRoot, normalizedPath));
    }
    private static string ResolveYooOutputDirectory(string outputPath)
    {
        string outputDir = ResolveOutputDirectory(outputPath);
        string normalizedOutputDir = NormalizeFullPath(outputDir);
        if (string.Equals(System.IO.Path.GetFileName(normalizedOutputDir), "yoo", StringComparison.OrdinalIgnoreCase))
        {
            return outputDir;
        }
        return System.IO.Path.Combine(outputDir, "yoo");
    }
    private static string NormalizeFullPath(string path)
    {
        return System.IO.Path.GetFullPath(path).TrimEnd('\\', '/').Replace('\\', '/');
    }
    private static int CopyDirectoryFiles(string sourceDir, string destDir)
    {
        System.IO.Directory.CreateDirectory(destDir);
        int copiedCount = 0;
        string sourceFullPath = NormalizeFullPath(sourceDir);
        foreach (var sourceFile in System.IO.Directory.GetFiles(sourceFullPath, "*", System.IO.SearchOption.AllDirectories))
        {
            if (string.Equals(System.IO.Path.GetExtension(sourceFile), ".meta", StringComparison.OrdinalIgnoreCase))
            {
                continue;
            }
            string relativePath = sourceFile.Substring(sourceFullPath.Length).TrimStart('\\', '/');
            string destFile = System.IO.Path.Combine(destDir, relativePath);
            string destFileDir = System.IO.Path.GetDirectoryName(destFile);
            if (!System.IO.Directory.Exists(destFileDir))
            {
                System.IO.Directory.CreateDirectory(destFileDir);
            }
            System.IO.File.Copy(sourceFile, destFile, true);
            copiedCount++;
        }
        return copiedCount;
    }
    public static bool CopyStartupConfigsToStreamingAssets()
@@ -768,6 +818,7 @@
            }
        }
        CopyStartupConfigsToStreamingAssets();
        Debug.Log($"[YooAssetBuildTool] 已从构建产物恢复 {copiedCount} 个文件到 StreamingAssets");
    }