| | |
| | | using System.Collections;
|
| | | using System.Collections;
|
| | | using System.Collections.Generic;
|
| | | using UnityEngine;
|
| | | using System;
|
| | |
| | | }
|
| | |
|
| | | public static VersionConfig versionConfig1 = null;
|
| | |
|
| | | /// <summary>
|
| | | /// 导出Android工程给AS打包
|
| | | /// Unity只负责导出unityLibrary,SDK/Gradle/签名等均由AS工程处理
|
| | | /// </summary>
|
| | | public static void ExportAndroidProject(string _publisher, int _buildIndex, bool _development, string _outputPath, string _assetBundlePath)
|
| | | {
|
| | | if (string.IsNullOrEmpty(_outputPath) || !Directory.Exists(_outputPath))
|
| | | {
|
| | | Debug.LogError("导出路径无效,请设置有效的 Android Export Path: " + _outputPath);
|
| | | return;
|
| | | }
|
| | |
|
| | | PreBuild(_publisher, _buildIndex);
|
| | |
|
| | | var versionName = string.Empty;
|
| | | var versionConfig = GetVersionConfig(_publisher, out versionName);
|
| | |
|
| | | PlayerSettings.Android.bundleVersionCode = VersionConfig.GetVersionNumber(versionConfig.version);
|
| | | PlayerSettings.enableInternalProfiler = _development;
|
| | |
|
| | | // 先清理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);
|
| | | }
|
| | |
|
| | | // 关键设置:导出为Gradle工程而非直接打APK
|
| | | EditorUserBuildSettings.exportAsGoogleAndroidProject = true;
|
| | | EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Gradle;
|
| | | EditorUserBuildSettings.development = _development;
|
| | |
|
| | | // 导出路径
|
| | | _outputPath = Path.GetFullPath(_outputPath);
|
| | | string outputDir = Path.Combine(_outputPath, versionName + "_" + versionConfig.clientPackageFlag);
|
| | |
|
| | | if (Directory.Exists(outputDir))
|
| | | {
|
| | | Directory.Delete(outputDir, true);
|
| | | }
|
| | |
|
| | | Debug.LogFormat("开始导出Android工程,输出路径: {0}", outputDir);
|
| | |
|
| | | BuildPipeline.BuildPlayer(baseLevels, outputDir, BuildTarget.Android,
|
| | | _development ? BuildOptions.AcceptExternalModificationsToPlayer | BuildOptions.Development | BuildOptions.AllowDebugging
|
| | | : BuildOptions.AcceptExternalModificationsToPlayer);
|
| | |
|
| | | Debug.LogFormat("导出Android工程完成!输出路径: {0}", outputDir);
|
| | |
|
| | | // 导出完成后恢复设置
|
| | | EditorUserBuildSettings.exportAsGoogleAndroidProject = false;
|
| | | EditorUserBuildSettings.development = false;
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 小包拷贝:仅拷贝builtin资源
|
| | | /// </summary>
|
| | | static void CopyNullAssetResources(string _assetBundlePath, string _streamingPath)
|
| | | {
|
| | | var files = new List<FileInfo>();
|
| | | var builtInFiles = new List<FileInfo>();
|
| | |
|
| | | FileExtersion.GetAllDirectoryFileInfos(_assetBundlePath, files);
|
| | | foreach (var file in files)
|
| | | {
|
| | | if (file.FullName.Contains("builtin"))
|
| | | {
|
| | | builtInFiles.Add(file);
|
| | | }
|
| | | }
|
| | |
|
| | | foreach (var item in builtInFiles)
|
| | | {
|
| | | var extension = Path.GetExtension(item.FullName);
|
| | | if (extension == ".meta")
|
| | | continue;
|
| | |
|
| | | var relativePath = FileExtersion.GetFileRelativePath(_assetBundlePath, item.FullName);
|
| | | var to = StringUtility.Concat(_streamingPath, relativePath);
|
| | | var directory = Path.GetDirectoryName(to);
|
| | | if (!Directory.Exists(directory))
|
| | | Directory.CreateDirectory(directory);
|
| | |
|
| | | File.Copy(item.FullName, to, true);
|
| | | }
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 半包拷贝:根据PriorBundleConfig剔除优先级低的hero/maps/audio/uieffect/video资源,
|
| | | /// 以及config和ui资源(取决于includeConfig/includeUI开关)
|
| | | /// </summary>
|
| | | static void CopyHalfAssetResources(string _assetBundlePath, string _streamingPath)
|
| | | {
|
| | | PriorBundleConfig.LazyInit();
|
| | |
|
| | | var fromFiles = new List<FileInfo>();
|
| | | FileExtersion.GetAllDirectoryFileInfos(_assetBundlePath, fromFiles);
|
| | |
|
| | | var excludeFileFullNames = new List<string>();
|
| | |
|
| | | // 剔除优先级低的hero资源
|
| | | var tempFiles = new List<FileInfo>();
|
| | | FileExtersion.GetAllDirectoryFileInfos(StringUtility.Concat(_assetBundlePath, "/hero"), tempFiles);
|
| | | foreach (var file in tempFiles)
|
| | | {
|
| | | var fileName = Path.GetFileNameWithoutExtension(file.FullName);
|
| | | var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Mob, AssetVersionUtility.DecodeFileName(fileName));
|
| | | if (prior > AssetPrior)
|
| | | {
|
| | | excludeFileFullNames.Add(file.FullName);
|
| | | }
|
| | | }
|
| | |
|
| | | // 剔除优先级低的maps资源
|
| | | tempFiles.Clear();
|
| | | FileExtersion.GetAllDirectoryFileInfos(StringUtility.Concat(_assetBundlePath, "/maps"), tempFiles);
|
| | | foreach (var file in tempFiles)
|
| | | {
|
| | | var fileName = Path.GetFileNameWithoutExtension(file.FullName);
|
| | | var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Scene, AssetVersionUtility.DecodeFileName(fileName));
|
| | | if (prior > AssetPrior)
|
| | | {
|
| | | excludeFileFullNames.Add(file.FullName);
|
| | | }
|
| | | }
|
| | |
|
| | | // 剔除优先级低的audio资源
|
| | | tempFiles.Clear();
|
| | | FileExtersion.GetAllDirectoryFileInfos(StringUtility.Concat(_assetBundlePath, "/audio"), tempFiles);
|
| | | foreach (var file in tempFiles)
|
| | | {
|
| | | var fileName = Path.GetFileNameWithoutExtension(file.FullName);
|
| | | var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Audio, AssetVersionUtility.DecodeFileName(fileName));
|
| | | if (prior > AssetPrior)
|
| | | {
|
| | | excludeFileFullNames.Add(file.FullName);
|
| | | }
|
| | | }
|
| | |
|
| | | // 剔除优先级低的uieffect资源
|
| | | tempFiles.Clear();
|
| | | FileExtersion.GetAllDirectoryFileInfos(StringUtility.Concat(_assetBundlePath, "/uieffect"), tempFiles);
|
| | | foreach (var file in tempFiles)
|
| | | {
|
| | | var fileName = Path.GetFileNameWithoutExtension(file.FullName);
|
| | | var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Effect, AssetVersionUtility.DecodeFileName(fileName));
|
| | | if (prior > AssetPrior)
|
| | | {
|
| | | excludeFileFullNames.Add(file.FullName);
|
| | | }
|
| | | }
|
| | |
|
| | | // 剔除视频资源
|
| | | tempFiles.Clear();
|
| | | var videoPath = StringUtility.Concat(_assetBundlePath, "/video");
|
| | | if (Directory.Exists(videoPath))
|
| | | {
|
| | | FileExtersion.GetAllDirectoryFileInfos(videoPath, tempFiles);
|
| | | foreach (var file in tempFiles)
|
| | | {
|
| | | var fileName = Path.GetFileNameWithoutExtension(file.FullName);
|
| | | var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Video, AssetVersionUtility.DecodeFileName(fileName));
|
| | | if (prior > AssetPrior)
|
| | | {
|
| | | excludeFileFullNames.Add(file.FullName);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | // 剔除表资源
|
| | | if (!includeConfig)
|
| | | {
|
| | | tempFiles.Clear();
|
| | | FileExtersion.GetAllDirectoryFileInfos(StringUtility.Concat(_assetBundlePath, "/config"), tempFiles);
|
| | | foreach (var file in tempFiles)
|
| | | {
|
| | | excludeFileFullNames.Add(file.FullName);
|
| | | }
|
| | | }
|
| | |
|
| | | // 剔除UI资源
|
| | | if (!includeUI)
|
| | | {
|
| | | tempFiles.Clear();
|
| | | FileExtersion.GetAllDirectoryFileInfos(StringUtility.Concat(_assetBundlePath, "/ui"), tempFiles);
|
| | | foreach (var file in tempFiles)
|
| | | {
|
| | | excludeFileFullNames.Add(file.FullName);
|
| | | }
|
| | | }
|
| | | else
|
| | | {
|
| | | tempFiles.Clear();
|
| | | FileExtersion.GetAllDirectoryFileInfos(StringUtility.Concat(_assetBundlePath, "/ui"), tempFiles);
|
| | | foreach (var file in tempFiles)
|
| | | {
|
| | | var fileName = Path.GetFileNameWithoutExtension(file.FullName);
|
| | | var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.UI, fileName);
|
| | | if (prior > AssetPrior)
|
| | | {
|
| | | excludeFileFullNames.Add(file.FullName);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | // 从文件列表中移除需要排除的文件
|
| | | for (int i = fromFiles.Count - 1; i >= 0; i--)
|
| | | {
|
| | | if (excludeFileFullNames.Contains(fromFiles[i].FullName))
|
| | | {
|
| | | fromFiles.RemoveAt(i);
|
| | | }
|
| | | }
|
| | |
|
| | | foreach (var item in fromFiles)
|
| | | {
|
| | | var extension = Path.GetExtension(item.FullName);
|
| | | if (extension == ".meta")
|
| | | continue;
|
| | |
|
| | | var relativePath = FileExtersion.GetFileRelativePath(_assetBundlePath, item.FullName);
|
| | | if (relativePath.StartsWith("patch"))
|
| | | continue;
|
| | |
|
| | | var to = StringUtility.Concat(_streamingPath, relativePath);
|
| | | var directory = Path.GetDirectoryName(to);
|
| | | if (!Directory.Exists(directory))
|
| | | Directory.CreateDirectory(directory);
|
| | |
|
| | | File.Copy(item.FullName, to, true);
|
| | | }
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 全包拷贝:拷贝所有资源(排除patch和.meta)
|
| | | /// </summary>
|
| | | static void CopyFullAssetResources(string _assetBundlePath, string _streamingPath)
|
| | | {
|
| | | var files = new List<FileInfo>();
|
| | | FileExtersion.GetAllDirectoryFileInfos(_assetBundlePath, files);
|
| | | foreach (var file in files)
|
| | | {
|
| | | var extension = Path.GetExtension(file.FullName);
|
| | | if (extension == ".meta")
|
| | | continue;
|
| | |
|
| | | var relativePath = FileExtersion.GetFileRelativePath(_assetBundlePath, file.FullName);
|
| | | if (relativePath.StartsWith("patch"))
|
| | | continue;
|
| | |
|
| | | var to = StringUtility.Concat(_streamingPath, relativePath);
|
| | | var directory = Path.GetDirectoryName(to);
|
| | | if (!Directory.Exists(directory))
|
| | | Directory.CreateDirectory(directory);
|
| | |
|
| | | File.Copy(file.FullName, to, true);
|
| | | }
|
| | | }
|
| | |
|
| | | public static void BuildIpa(string _sdkPath, string _publisher, int _buildIndex, bool _replace)
|
| | | {
|
| | | PreBuild(_publisher, _buildIndex);
|