SDK_UnityMoney/Assets/Editor/PackageExporter.cs

273 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
public class PackageExporter
{
/// <summary>
/// 导出 UnityPackage支持忽略特定文件
/// </summary>
/// <param name="assetPaths">需要导出的资源路径数组(文件夹或文件)</param>
/// <param name="outputPath">导出文件路径(含.unitypackage扩展名</param>
/// <param name="ignorePatterns">需要忽略的文件/文件夹模式数组</param>
/// <param name="includeDependencies">是否包含依赖资源</param>
/// <param name="recurseFolders">是否递归导出文件夹内的所有内容</param>
/// <returns>导出是否成功</returns>
private static bool ExportUnityPackage(
string[] assetPaths,
string outputPath,
string[] ignorePatterns = null,
bool includeDependencies = true,
bool recurseFolders = true
)
{
// 1. 验证资源路径
if (!ValidateAssetPaths(assetPaths))
{
Debug.LogError("导出失败:无效的资源路径");
return false;
}
// 2. 验证输出路径
if (!ValidateAndPrepareOutputPath(outputPath))
{
Debug.LogError("导出失败:无效的输出路径");
return false;
}
try
{
// 3. 处理需要导出的路径(过滤掉需要忽略的文件)
var temp = ProcessAssetPaths(assetPaths, ignorePatterns, recurseFolders);
var filteredPaths = temp.Where(File.Exists).ToArray();
if (filteredPaths.Length == 0)
{
Debug.LogError("导出失败:所有路径都被过滤掉了");
return false;
}
// 4. 构建导出选项
ExportPackageOptions options = ExportPackageOptions.Default;
// 如果需要递归文件夹,添加 Recurse 选项
if (recurseFolders)
{
options |= ExportPackageOptions.Recurse;
}
// 如果需要包含依赖资源,添加 IncludeDependencies 选项
if (includeDependencies)
{
options |= ExportPackageOptions.IncludeDependencies;
}
// 5. 执行导出
AssetDatabase.ExportPackage(filteredPaths, outputPath, options);
// 6. 验证结果
if (File.Exists(outputPath))
{
Debug.Log($"导出成功:{outputPath}");
return true;
}
Debug.LogError("导出失败:文件未生成");
return false;
}
catch (Exception ex)
{
Debug.LogError($"导出异常:{ex.Message}");
return false;
}
}
/// <summary>
/// 处理资源路径,过滤掉需要忽略的文件
/// </summary>
private static string[] ProcessAssetPaths(string[] assetPaths, string[] ignorePatterns, bool recurseFolders)
{
if (ignorePatterns == null || ignorePatterns.Length == 0)
{
return assetPaths; // 没有需要忽略的模式,直接返回原路径
}
// 收集所有需要导出的文件路径
var allFiles = new System.Collections.Generic.List<string>();
foreach (var path in assetPaths)
{
if (AssetDatabase.IsValidFolder(path))
{
// 如果是文件夹,获取所有文件
var filesInFolder = AssetDatabase.FindAssets("", new[] { path })
.Select(AssetDatabase.GUIDToAssetPath)
.ToArray();
// 根据递归选项和忽略模式过滤文件
allFiles.AddRange(filesInFolder.Where(file => !ShouldIgnore(file, ignorePatterns) && (recurseFolders || Path.GetDirectoryName(file) == path)));
var googleMobileAdsAndroidLib = Directory.GetDirectories(path, "GoogleMobileAdsPlugin", SearchOption.AllDirectories)
.Where(p => p.Replace("\\", "/").StartsWith("Assets/"))
.Select(p => p.Replace("\\", "/"))
.ToArray();
Debug.Log("yangwu firebase:"+googleMobileAdsAndroidLib);
allFiles.AddRange(googleMobileAdsAndroidLib);
}
else if (File.Exists(path))
{
// 如果是文件,检查是否需要忽略
if (!ShouldIgnore(path, ignorePatterns))
{
allFiles.Add(path);
}
}
var androidLibs = Directory.GetDirectories(path, "GoogleMobileAdsPlugin.androidlib", SearchOption.AllDirectories)
.Where(p => p.Replace("\\", "/").StartsWith("Assets/"))
.Select(p => p.Replace("\\", "/"))
.ToArray();
allFiles.AddRange(androidLibs);
}
return allFiles.Distinct().ToArray();
}
/// <summary>
/// 检查文件是否应该被忽略
/// </summary>
private static bool ShouldIgnore(string filePath, string[] ignorePatterns)
{
if (!ignorePatterns.Any(pattern => filePath.Contains(pattern) ||
Path.GetFileName(filePath).Contains(pattern) ||
(pattern.Contains("*") && MatchesWildcard(filePath, pattern)))) return false;
Debug.Log("ShouldIgnore true: " + filePath);
return true;
}
/// <summary>
/// 检查文件路径是否匹配通配符模式(使用正则表达式实现)
/// </summary>
private static bool MatchesWildcard(string filePath, string pattern)
{
try
{
// 将通配符模式转换为正则表达式
var regexPattern = "^" + Regex.Escape(pattern).Replace("\\*", ".*").Replace("\\?", ".") + "$";
var regex = new Regex(regexPattern, RegexOptions.IgnoreCase);
// 检查文件名和完整路径是否匹配
return regex.IsMatch(Path.GetFileName(filePath)) || regex.IsMatch(filePath);
}
catch
{
return false;
}
}
// 以下为辅助方法
private static bool ValidateAssetPaths(string[] assetPaths)
{
if (assetPaths == null || assetPaths.Length == 0)
{
Debug.LogWarning("未指定任何资源路径");
return false;
}
foreach (var path in assetPaths)
{
if (string.IsNullOrWhiteSpace(path) || !path.StartsWith("Assets/"))
{
Debug.LogWarning($"无效路径格式:{path}(必须以 Assets/ 开头)");
return false;
}
if (AssetDatabase.IsValidFolder(path) || File.Exists(path)) continue;
Debug.LogWarning($"路径不存在:{path}");
return false;
}
return true;
}
private static bool ValidateAndPrepareOutputPath(string outputPath)
{
if (string.IsNullOrWhiteSpace(outputPath) || !outputPath.EndsWith(".unitypackage"))
{
Debug.LogWarning("输出路径必须包含 .unitypackage 扩展名");
return false;
}
var directory = Path.GetDirectoryName(outputPath);
if (Directory.Exists(directory)) return true;
try
{
if (directory == null)
{
return false;
}
Directory.CreateDirectory(directory);
}
catch (Exception ex)
{
Debug.LogError($"无法创建目录:{ex.Message}");
return false;
}
return true;
}
// ------------------------------
// 快捷导出示例(可直接在菜单调用)
// ------------------------------
[MenuItem("Tools/Export UnityPackage")]
public static void ExportExamplePackage()
{
var pathsToExport = new[]
{
"Assets/Adjust",
"Assets/BigoAds",
"Assets/BigoSDK",
"Assets/Editor",
"Assets/Editor Default Resources",
"Assets/ExternalDependencyManager",
"Assets/EFSDK",
"Assets/Firebase",
"Assets/GeneratedLocalRepo",
"Assets/GoogleMobileAds",
"Assets/KwaiAds",
"Assets/MaxSdk",
"Assets/Plugins",
"Assets/Script",
"Assets/ThinkingAnalytics",
"Assets/ThinkupTpnPlugin",
"Assets/UnityPackages"
};
// 定义需要忽略的文件/文件夹模式
var ignorePatterns = new[]
{
"Assets/Plugins/Android/AndroidManifest.xml",
"Assets/Plugins/Android/baseProjectTemplate.gradle",
"Assets/Plugins/Android/gradleTemplate.properties",
"Assets/Plugins/Android/LauncherManifest.xml",
"Assets/Plugins/Android/launcherTemplate.gradle",
"Assets/Plugins/Android/mainTemplate.gradle",
"Assets/Plugins/Android/MessagingUnityPlayerActivity.java",
"Assets/Plugins/Android/settingsTemplate.gradle",
};
// 获取项目根目录Assets文件夹的上级目录
var projectRoot = Path.GetFullPath(Path.Combine(Application.dataPath, ".."));
var outputPath = Path.Combine(projectRoot, $"RushSDK_{RushSDKManager.GetSDKVersion()}_{DateTime.Now:yyyyMMdd_HHmmss}.unitypackage");
// 执行导出(不包含依赖,使用我们定义的忽略模式)
ExportUnityPackage(pathsToExport, outputPath, ignorePatterns, includeDependencies: false);
}
}