添加个人信息打包的unity工程
parent
4c61e0a668
commit
a69cfc43dd
|
|
@ -0,0 +1,22 @@
|
||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 09788b4733bab2d4792fdd5d28e7653c, type: 3}
|
||||||
|
m_Name: AssetBundleBuilderSetting
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
BuildPipeline: 1
|
||||||
|
BuildMode: 1
|
||||||
|
BuildPackage: DefaultPackage
|
||||||
|
CompressOption: 2
|
||||||
|
OutputNameStyle: 1
|
||||||
|
CopyBuildinFileOption: 1
|
||||||
|
CopyBuildinFileTags:
|
||||||
|
EncyptionClassName: FileStreamEncryption
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fe4cb5ddc6c5d4769924469cce0011ed
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 185f6993d5150494d98da50e26cb1c25, type: 3}
|
||||||
|
m_Name: AssetBundleCollectorSetting
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
ShowPackageView: 1
|
||||||
|
EnableAddressable: 1
|
||||||
|
LocationToLower: 0
|
||||||
|
IncludeAssetGUID: 0
|
||||||
|
UniqueBundleName: 1
|
||||||
|
ShowEditorAlias: 1
|
||||||
|
Packages:
|
||||||
|
- PackageName: DefaultPackage
|
||||||
|
PackageDesc: "\u9ED8\u8BA4\u8D44\u6E90\u5305"
|
||||||
|
Groups:
|
||||||
|
- GroupName: UIRaw
|
||||||
|
GroupDesc: "\u56FE\u7247\u8D44\u6E90"
|
||||||
|
AssetTags: UIRaw
|
||||||
|
ActiveRuleName: EnableGroup
|
||||||
|
Collectors:
|
||||||
|
- CollectPath: Assets/AssetRaw/UIRaw/Raw/Thum
|
||||||
|
CollectorGUID: c2d4a782dcb034673a46135eff2152c3
|
||||||
|
CollectorType: 0
|
||||||
|
AddressRuleName: AddressByFileName
|
||||||
|
PackRuleName: PackSeparately
|
||||||
|
FilterRuleName: CollectSprite
|
||||||
|
AssetTags:
|
||||||
|
UserData:
|
||||||
|
- CollectPath: Assets/AssetRaw/UIRaw/Raw/Level/main
|
||||||
|
CollectorGUID: 1c17b617b71c34255ac4108d736950ed
|
||||||
|
CollectorType: 0
|
||||||
|
AddressRuleName: AddressByFileName
|
||||||
|
PackRuleName: PackTopDirectory
|
||||||
|
FilterRuleName: CollectAll
|
||||||
|
AssetTags:
|
||||||
|
UserData:
|
||||||
|
- CollectPath: Assets/AssetRaw/UIRaw/Raw/Level/colorfun
|
||||||
|
CollectorGUID: 8c41414d13c2749c38819bf9f9c32257
|
||||||
|
CollectorType: 0
|
||||||
|
AddressRuleName: AddressByFileName
|
||||||
|
PackRuleName: PackTopDirectory
|
||||||
|
FilterRuleName: CollectAll
|
||||||
|
AssetTags:
|
||||||
|
UserData:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9e01483f3dd3c4f2abcbe9fbd3bb5a76
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a02d2cfa67b2346c889f631727b3e25e
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
项目AB资源软链接文件夹(和资源工程文件夹名称保持一致)
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3f1ca26670fc7465ea399367ef61f8e1
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f85f4e5a623742589d2e8496bbb1892f
|
||||||
|
timeCreated: 1702539544
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditor.U2D;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.U2D;
|
||||||
|
|
||||||
|
public static class AtlasUtils
|
||||||
|
{
|
||||||
|
public static SpriteAtlas CreateAtlas(string name, List<Sprite> sprites, string path, int packPadding = 2,
|
||||||
|
FilterMode filterMode = FilterMode.Bilinear,
|
||||||
|
int maxTextureSize = 2048,
|
||||||
|
TextureImporterFormat androidFormat = TextureImporterFormat.ASTC_6x6,
|
||||||
|
TextureImporterFormat iosFormat = TextureImporterFormat.ASTC_6x6)
|
||||||
|
{
|
||||||
|
SpriteAtlas spriteAtlas = new SpriteAtlas();
|
||||||
|
spriteAtlas.Add(sprites.ToArray());
|
||||||
|
spriteAtlas.SetProjectCommonSetting(name, packPadding, filterMode, maxTextureSize, androidFormat, iosFormat);
|
||||||
|
string assetPath = $"{path}/{spriteAtlas.name}.spriteatlas";
|
||||||
|
if (File.Exists(assetPath))
|
||||||
|
{
|
||||||
|
File.Delete(assetPath);
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
|
AssetDatabase.CreateAsset(spriteAtlas,$"{path}/{spriteAtlas.name}.spriteatlas");
|
||||||
|
return spriteAtlas;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static partial class Extensions
|
||||||
|
{
|
||||||
|
public static SpriteAtlas SetProjectCommonSetting(this SpriteAtlas spriteAtlas, string name, int packPadding = 2,
|
||||||
|
FilterMode filterMode = FilterMode.Bilinear,
|
||||||
|
int maxTextureSize = 2048,
|
||||||
|
TextureImporterFormat androidFormat = TextureImporterFormat.ASTC_6x6,
|
||||||
|
TextureImporterFormat iosFormat = TextureImporterFormat.ASTC_6x6)
|
||||||
|
{
|
||||||
|
spriteAtlas.name = name;
|
||||||
|
spriteAtlas.SetCommonPackingSetting(packPadding)
|
||||||
|
.SetCommonTextureSetting(filterMode)
|
||||||
|
.SetCommonAndroidTextureSettings(maxTextureSize, androidFormat)
|
||||||
|
.SetCommonIOSTextureSettings(maxTextureSize, iosFormat);
|
||||||
|
return spriteAtlas;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SpriteAtlas SetCommonPackingSetting(this SpriteAtlas spriteAtlas, int padding = 2)
|
||||||
|
{
|
||||||
|
SpriteAtlasPackingSettings packingSettings = new SpriteAtlasPackingSettings
|
||||||
|
{
|
||||||
|
enableTightPacking = false,
|
||||||
|
enableRotation = false,
|
||||||
|
blockOffset = 1,
|
||||||
|
padding = padding
|
||||||
|
};
|
||||||
|
spriteAtlas.SetPackingSettings(packingSettings);
|
||||||
|
return spriteAtlas;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SpriteAtlas SetCommonTextureSetting(this SpriteAtlas spriteAtlas, FilterMode filterMode = FilterMode.Bilinear)
|
||||||
|
{
|
||||||
|
SpriteAtlasTextureSettings textureSettings = new SpriteAtlasTextureSettings
|
||||||
|
{
|
||||||
|
readable = false,
|
||||||
|
anisoLevel = 1,
|
||||||
|
filterMode = filterMode,
|
||||||
|
generateMipMaps = false,
|
||||||
|
sRGB = true
|
||||||
|
};
|
||||||
|
spriteAtlas.SetTextureSettings(textureSettings);
|
||||||
|
return spriteAtlas;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SpriteAtlas SetCommonAndroidTextureSettings(this SpriteAtlas spriteAtlas, int maxTextureSize = 2048, TextureImporterFormat format = TextureImporterFormat.ASTC_6x6)
|
||||||
|
{
|
||||||
|
TextureImporterPlatformSettings settings = new TextureImporterPlatformSettings
|
||||||
|
{
|
||||||
|
name = "Android",
|
||||||
|
maxTextureSize = maxTextureSize,
|
||||||
|
format = format,
|
||||||
|
overridden = true,
|
||||||
|
textureCompression = TextureImporterCompression.Compressed
|
||||||
|
};
|
||||||
|
spriteAtlas.SetPlatformSettings(settings);
|
||||||
|
return spriteAtlas;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SpriteAtlas SetCommonIOSTextureSettings(this SpriteAtlas spriteAtlas, int maxTextureSize = 2048, TextureImporterFormat format = TextureImporterFormat.ASTC_4x4)
|
||||||
|
{
|
||||||
|
TextureImporterPlatformSettings settings = new TextureImporterPlatformSettings
|
||||||
|
{
|
||||||
|
name = "iPhone",
|
||||||
|
maxTextureSize = maxTextureSize,
|
||||||
|
format = format,
|
||||||
|
overridden = true,
|
||||||
|
textureCompression = TextureImporterCompression.Compressed
|
||||||
|
};
|
||||||
|
spriteAtlas.SetPlatformSettings(settings);
|
||||||
|
return spriteAtlas;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 987faa5215d04a7a84736a2514261cdb
|
||||||
|
timeCreated: 1703644705
|
||||||
|
|
@ -0,0 +1,327 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using TEngine.Editor.Resource;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditor.U2D;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.U2D;
|
||||||
|
using YooAsset.Editor;
|
||||||
|
|
||||||
|
public static class BuildBundlesHelper
|
||||||
|
{
|
||||||
|
private static BuildParameters GetParametersFromParams(BuildTarget buildTarget, string buildVersion)
|
||||||
|
{
|
||||||
|
BuildParameters buildParameters = new BuildParameters()
|
||||||
|
{
|
||||||
|
StreamingAssetsRoot = AssetBundleBuilderHelper.GetDefaultStreamingAssetsRoot(),
|
||||||
|
BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot(),
|
||||||
|
BuildTarget = buildTarget,
|
||||||
|
BuildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline,
|
||||||
|
BuildMode = AssetBundleBuilderSettingData.Setting.BuildMode,
|
||||||
|
PackageName = AssetBundleBuilderSettingData.Setting.BuildPackage,
|
||||||
|
PackageVersion = buildVersion,
|
||||||
|
VerifyBuildingResult = true,
|
||||||
|
SharedPackRule = new ZeroRedundancySharedPackRule(),
|
||||||
|
EncryptionServices = new FileStreamEncryption(),
|
||||||
|
CompressOption = AssetBundleBuilderSettingData.Setting.CompressOption,
|
||||||
|
OutputNameStyle = AssetBundleBuilderSettingData.Setting.OutputNameStyle,
|
||||||
|
CopyBuildinFileOption = ECopyBuildinFileOption.None,
|
||||||
|
CopyBuildinFileTags = AssetBundleBuilderSettingData.Setting.CopyBuildinFileTags,
|
||||||
|
EnableLog = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (AssetBundleBuilderSettingData.Setting.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
|
||||||
|
{
|
||||||
|
buildParameters.SBPParameters = new BuildParameters.SBPBuildParameters();
|
||||||
|
buildParameters.SBPParameters.WriteLinkXML = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buildParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("Tools/TestBuildBundles")]
|
||||||
|
public static void TestBuildBundles()
|
||||||
|
{
|
||||||
|
|
||||||
|
Debug.LogWarning("MakeAtlas Start ==================");
|
||||||
|
MakeAtlas();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
Debug.LogWarning("MakeAtlas End ==================");
|
||||||
|
|
||||||
|
Debug.LogWarning("Create YooAsset Package Start ==========");
|
||||||
|
CreateYooAssetPackage();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
Debug.LogWarning("Create YooAsset Package End ==========");
|
||||||
|
|
||||||
|
Debug.LogWarning("BuildBundles Start ==================");
|
||||||
|
AssetBundleCollectorSetting setting = AssetDatabase.LoadAssetAtPath<AssetBundleCollectorSetting>("Assets/AssetBundleCollectorSetting.asset");
|
||||||
|
if (setting == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("不存在的AssetBundleCollectorSetting.asset");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var bundleBuilder = new AssetBundleBuilder();
|
||||||
|
BuildParameters buildParameters = GetParametersFromParams(BuildTarget.Android, "1.0.0");
|
||||||
|
string outputDir = $"{buildParameters.BuildOutputRoot}/{buildParameters.BuildTarget.ToString()}";
|
||||||
|
Debug.LogError($"bundle资源输出目录:{outputDir}");
|
||||||
|
if (Directory.Exists(outputDir))
|
||||||
|
Directory.Delete(outputDir, true);
|
||||||
|
|
||||||
|
for (int i = 0; i < setting.Packages.Count; i++)
|
||||||
|
{
|
||||||
|
var package = setting.Packages[i];
|
||||||
|
if(package.PackageName == "DefaultPackage")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
buildParameters.PackageName = package.PackageName;
|
||||||
|
bundleBuilder.Run(buildParameters);
|
||||||
|
}
|
||||||
|
Debug.LogWarning("BuildBundles End ==================");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BuildBundles()
|
||||||
|
{
|
||||||
|
Debug.LogWarning("MakeAtlas Start ==================");
|
||||||
|
MakeAtlas();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
Debug.LogWarning("MakeAtlas End ==================");
|
||||||
|
|
||||||
|
Debug.LogWarning("Create YooAsset Package Start ==========");
|
||||||
|
CreateYooAssetPackage();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
Debug.LogWarning("Create YooAsset Package End ==========");
|
||||||
|
|
||||||
|
Debug.LogWarning("BuildBundles Start ==================");
|
||||||
|
AssetBundleCollectorSetting setting = AssetDatabase.LoadAssetAtPath<AssetBundleCollectorSetting>("Assets/AssetBundleCollectorSetting.asset");
|
||||||
|
if (setting == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("不存在的AssetBundleCollectorSetting.asset");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BuildParams bp = BuildParamsHelper.GetBuildParams();
|
||||||
|
bp.Description();
|
||||||
|
var bundleBuilder = new AssetBundleBuilder();
|
||||||
|
BuildParameters buildParameters = null;
|
||||||
|
if (bp.Platform == "Android")
|
||||||
|
buildParameters = GetParametersFromParams(BuildTarget.Android, bp.BuildVersion);
|
||||||
|
else if (bp.Platform == "iOS")
|
||||||
|
buildParameters = GetParametersFromParams(BuildTarget.iOS, bp.BuildVersion);
|
||||||
|
if (buildParameters == null)
|
||||||
|
{
|
||||||
|
Debug.LogError($"不支持的平台:{bp.Platform}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string outputDir = $"{buildParameters.BuildOutputRoot}/{buildParameters.BuildTarget.ToString()}";
|
||||||
|
Debug.LogError($"bundle资源输出目录:{outputDir}");
|
||||||
|
if (Directory.Exists(outputDir))
|
||||||
|
Directory.Delete(outputDir, true);
|
||||||
|
|
||||||
|
for (int i = 0; i < setting.Packages.Count; i++)
|
||||||
|
{
|
||||||
|
var package = setting.Packages[i];
|
||||||
|
if(package.PackageName == "DefaultPackage")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
buildParameters.PackageName = package.PackageName;
|
||||||
|
bundleBuilder.Run(buildParameters);
|
||||||
|
}
|
||||||
|
Debug.LogWarning("BuildBundles End ==================> exe");
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 创建图集
|
||||||
|
|
||||||
|
private static void MakeAtlas()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (int)GamePlay.end; i++)
|
||||||
|
{
|
||||||
|
GamePlay playType = (GamePlay)i;
|
||||||
|
string dir = $"Assets/AssetRaw/UIRaw/Raw/Level/{playType.ToString()}";
|
||||||
|
if (!AssetDatabase.IsValidFolder(dir))
|
||||||
|
{
|
||||||
|
Debug.LogError($"不存在的目录:{dir}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var playTypeAllLevelDirs = AssetDatabase.GetSubFolders(dir);
|
||||||
|
foreach (var levelDir in playTypeAllLevelDirs)
|
||||||
|
{
|
||||||
|
string levelName = levelDir.Substring(levelDir.LastIndexOf('/') + 1);
|
||||||
|
MakeLevelAtlas(levelDir, levelName);
|
||||||
|
string itemDirPath = $"{levelDir}/titem";
|
||||||
|
if (!AssetDatabase.IsValidFolder(itemDirPath))
|
||||||
|
{
|
||||||
|
Debug.LogError($"不存在的道具图:{itemDirPath}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MakeItemAtlas(itemDirPath, levelName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void MakeItemAtlas(string dirPath, string levelName)
|
||||||
|
{
|
||||||
|
string[] allPics = Directory.GetFiles(dirPath, "*.png", SearchOption.TopDirectoryOnly);
|
||||||
|
if (allPics.Length == 0)
|
||||||
|
{
|
||||||
|
Debug.LogError($"不存在的道具图:{dirPath}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Sprite> sprites = new List<Sprite>();
|
||||||
|
foreach (var picPath in allPics)
|
||||||
|
{
|
||||||
|
if(picPath.EndsWith(".meta"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (picPath.Contains("_titem_"))
|
||||||
|
{
|
||||||
|
var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(picPath);
|
||||||
|
if (sprite != null)
|
||||||
|
{
|
||||||
|
sprites.Add(sprite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AtlasUtils.CreateAtlas($"{levelName}_atlasItem", sprites, dirPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void MakeLevelAtlas(string levelDir, string levelName)
|
||||||
|
{
|
||||||
|
string[] allPics = Directory.GetFiles(levelDir, "*.png", SearchOption.TopDirectoryOnly);
|
||||||
|
if (allPics.Length == 0)
|
||||||
|
{
|
||||||
|
Debug.LogError($"不存在的关卡图:{levelDir}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Sprite> sprites = new List<Sprite>();
|
||||||
|
foreach (var picPath in allPics)
|
||||||
|
{
|
||||||
|
if(picPath.EndsWith(".meta"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (picPath.Contains("_tfull_") || picPath.Contains("_tmask_") || picPath.Contains("_tlight_") || picPath.Contains("_tshadow_"))
|
||||||
|
{
|
||||||
|
var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(picPath);
|
||||||
|
if (sprite != null)
|
||||||
|
{
|
||||||
|
sprites.Add(sprite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AtlasUtils.CreateAtlas($"{levelName}_atlasLevel", sprites, levelDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private static void CreateYooAssetPackage()
|
||||||
|
{
|
||||||
|
AssetBundleCollectorSetting setting = AssetDatabase.LoadAssetAtPath<AssetBundleCollectorSetting>("Assets/AssetBundleCollectorSetting.asset");
|
||||||
|
if (setting == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("不存在的AssetBundleCollectorSetting.asset");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//重置配置
|
||||||
|
for (int i = 0; i < setting.Packages.Count; i++)
|
||||||
|
{
|
||||||
|
if(setting.Packages[i].PackageName == "DefaultPackage")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
setting.Packages.RemoveAt(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
Debug.Log($"packge count:{setting.Packages.Count}");
|
||||||
|
|
||||||
|
//创建关卡资源package
|
||||||
|
for (int i = 0; i < (int)GamePlay.end; i++)
|
||||||
|
{
|
||||||
|
GamePlay playType = (GamePlay)i;
|
||||||
|
string dir = $"Assets/AssetRaw/UIRaw/Raw/Level/{playType.ToString()}";
|
||||||
|
if (!AssetDatabase.IsValidFolder(dir))
|
||||||
|
{
|
||||||
|
Debug.LogError($"不存在的目录:{dir}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var playTypeAllLevelDirs = AssetDatabase.GetSubFolders(dir);
|
||||||
|
foreach (var levelDir in playTypeAllLevelDirs)
|
||||||
|
{
|
||||||
|
string levelName = levelDir.Substring(levelDir.LastIndexOf('/') + 1);
|
||||||
|
AssetBundleCollectorPackage package = new AssetBundleCollectorPackage();
|
||||||
|
package.PackageName = levelName;
|
||||||
|
package.PackageDesc = $"{levelName}关卡资源包";
|
||||||
|
package.Groups = new List<AssetBundleCollectorGroup>();
|
||||||
|
|
||||||
|
AssetBundleCollectorGroup group = new AssetBundleCollectorGroup();
|
||||||
|
group.GroupName = "default";
|
||||||
|
group.AssetTags = levelName;
|
||||||
|
group.ActiveRuleName = "EnableGroup";
|
||||||
|
group.Collectors = new List<AssetBundleCollector>();
|
||||||
|
|
||||||
|
AssetBundleCollector collector = new AssetBundleCollector();
|
||||||
|
collector.CollectPath = levelDir;
|
||||||
|
collector.CollectorGUID = AssetDatabase.AssetPathToGUID(collector.CollectPath);
|
||||||
|
collector.CollectorType = ECollectorType.MainAssetCollector;
|
||||||
|
collector.AddressRuleName = nameof(AddressByFileName);
|
||||||
|
collector.PackRuleName = nameof(PackCollector);
|
||||||
|
collector.FilterRuleName = nameof(CollectAll);
|
||||||
|
collector.AssetTags = levelName;
|
||||||
|
|
||||||
|
group.Collectors.Add(collector);
|
||||||
|
package.Groups.Add(group);
|
||||||
|
|
||||||
|
setting.Packages.Add(package);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//创建关卡缩略图package
|
||||||
|
for (int i = 0; i < (int)GamePlay.end; i++)
|
||||||
|
{
|
||||||
|
GamePlay playType = (GamePlay)i;
|
||||||
|
string dir = $"Assets/AssetRaw/UIRaw/Raw/Thum/{playType.ToString()}";
|
||||||
|
if (!AssetDatabase.IsValidFolder(dir))
|
||||||
|
{
|
||||||
|
Debug.LogError($"不存在的目录:{dir}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var thumFiles = Directory.GetFiles(dir);
|
||||||
|
foreach (var thumFile in thumFiles)
|
||||||
|
{
|
||||||
|
if(thumFile.EndsWith(".meta"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string levelName = Path.GetFileNameWithoutExtension(thumFile);
|
||||||
|
AssetBundleCollectorPackage package = new AssetBundleCollectorPackage();
|
||||||
|
package.PackageName = levelName;
|
||||||
|
package.PackageDesc = $"{levelName}缩略图资源包";
|
||||||
|
package.Groups = new List<AssetBundleCollectorGroup>();
|
||||||
|
|
||||||
|
AssetBundleCollectorGroup group = new AssetBundleCollectorGroup();
|
||||||
|
group.GroupName = "default";
|
||||||
|
group.AssetTags = levelName;
|
||||||
|
group.ActiveRuleName = "EnableGroup";
|
||||||
|
group.Collectors = new List<AssetBundleCollector>();
|
||||||
|
|
||||||
|
AssetBundleCollector collector = new AssetBundleCollector();
|
||||||
|
collector.CollectPath = thumFile;
|
||||||
|
collector.CollectorGUID = AssetDatabase.AssetPathToGUID(collector.CollectPath);
|
||||||
|
collector.CollectorType = ECollectorType.MainAssetCollector;
|
||||||
|
collector.AddressRuleName = nameof(AddressByFileName);
|
||||||
|
collector.PackRuleName = nameof(PackDirectory);
|
||||||
|
collector.FilterRuleName = nameof(CollectAll);
|
||||||
|
collector.AssetTags = levelName;
|
||||||
|
|
||||||
|
group.Collectors.Add(collector);
|
||||||
|
package.Groups.Add(group);
|
||||||
|
|
||||||
|
setting.Packages.Add(package);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetDatabase.SaveAssetIfDirty(setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5bd0d3c899424e118aa507af0ecf7149
|
||||||
|
timeCreated: 1702540933
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Unity.Plastic.Newtonsoft.Json;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class BuildParams
|
||||||
|
{
|
||||||
|
//版本号
|
||||||
|
public string AppVersion = "";
|
||||||
|
|
||||||
|
//资源版本号
|
||||||
|
public string ResVersion = "";
|
||||||
|
|
||||||
|
//build
|
||||||
|
public string BuildVersion = "";
|
||||||
|
|
||||||
|
//平台
|
||||||
|
public string Platform = "";
|
||||||
|
|
||||||
|
//打包类型
|
||||||
|
public string BuildType = "";
|
||||||
|
|
||||||
|
//是否Relase 或者 debug
|
||||||
|
public string Mode = "";
|
||||||
|
|
||||||
|
//CDN输出源
|
||||||
|
public string ResourceRoot = "";
|
||||||
|
|
||||||
|
public void Description()
|
||||||
|
{
|
||||||
|
Debug.Log("AppVersion = " + AppVersion);
|
||||||
|
Debug.Log("BuildVersion = " + BuildVersion);
|
||||||
|
Debug.Log("Platform = " + Platform);
|
||||||
|
Debug.Log("BuildType = " + BuildType);
|
||||||
|
Debug.Log("Mode = " + Mode);
|
||||||
|
Debug.Log("ResourceRoot = " + ResourceRoot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BuildParamsHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 根据jenkins的参数读取到BuildParams里
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static BuildParams GetBuildParams()
|
||||||
|
{
|
||||||
|
string[] parameters = Environment.GetCommandLineArgs();
|
||||||
|
BuildParams BuildParams = new BuildParams();
|
||||||
|
foreach (string str in parameters)
|
||||||
|
{
|
||||||
|
if (str.StartsWith("AppVersion"))
|
||||||
|
{
|
||||||
|
var tempParam = str.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (tempParam.Length == 2)
|
||||||
|
{
|
||||||
|
BuildParams.AppVersion = tempParam[1].Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (str.StartsWith("BuildVersion"))
|
||||||
|
{
|
||||||
|
var tempParam = str.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (tempParam.Length == 2)
|
||||||
|
{
|
||||||
|
BuildParams.BuildVersion = tempParam[1].Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (str.StartsWith("ResVersion"))
|
||||||
|
{
|
||||||
|
var tempParam = str.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (tempParam.Length == 2)
|
||||||
|
{
|
||||||
|
BuildParams.ResVersion = tempParam[1].Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (str.StartsWith("Platform"))
|
||||||
|
{
|
||||||
|
var tempParam = str.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (tempParam.Length == 2)
|
||||||
|
{
|
||||||
|
BuildParams.Platform = tempParam[1].Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (str.StartsWith("BuildType"))
|
||||||
|
{
|
||||||
|
var tempParam = str.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (tempParam.Length == 2)
|
||||||
|
{
|
||||||
|
BuildParams.BuildType = tempParam[1].Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (str.StartsWith("Mode"))
|
||||||
|
{
|
||||||
|
var tempParam = str.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (tempParam.Length == 2)
|
||||||
|
{
|
||||||
|
BuildParams.Mode = tempParam[1].Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (str.StartsWith("ResourceRoot"))
|
||||||
|
{
|
||||||
|
var tempParam = str.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (tempParam.Length == 2)
|
||||||
|
{
|
||||||
|
BuildParams.ResourceRoot = tempParam[1].Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return BuildParams;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c469487362bc4eb0a8e5790325ec8a97
|
||||||
|
timeCreated: 1702885370
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using YooAsset;
|
||||||
|
|
||||||
|
namespace TEngine.Editor.Resource
|
||||||
|
{
|
||||||
|
public class FileOffsetEncryption : IEncryptionServices
|
||||||
|
{
|
||||||
|
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
|
||||||
|
{
|
||||||
|
int offset = 32;
|
||||||
|
byte[] fileData = File.ReadAllBytes(fileInfo.FilePath);
|
||||||
|
var encryptedData = new byte[fileData.Length + offset];
|
||||||
|
Buffer.BlockCopy(fileData, 0, encryptedData, offset, fileData.Length);
|
||||||
|
|
||||||
|
EncryptResult result = new EncryptResult();
|
||||||
|
result.LoadMethod = EBundleLoadMethod.LoadFromFileOffset;
|
||||||
|
result.EncryptedData = encryptedData;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FileStreamEncryption : IEncryptionServices
|
||||||
|
{
|
||||||
|
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
|
||||||
|
{
|
||||||
|
// LoadFromStream
|
||||||
|
var fileData = File.ReadAllBytes(fileInfo.FilePath);
|
||||||
|
for (int i = 0; i < fileData.Length; i++)
|
||||||
|
{
|
||||||
|
fileData[i] ^= 128;
|
||||||
|
}
|
||||||
|
|
||||||
|
EncryptResult result = new EncryptResult();
|
||||||
|
result.LoadMethod = EBundleLoadMethod.LoadFromStream;
|
||||||
|
result.EncryptedData = fileData;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7f274ff1cb324de49164268263e60e5c
|
||||||
|
timeCreated: 1702879548
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
public enum GamePlay
|
||||||
|
{
|
||||||
|
main = 0, //主玩法
|
||||||
|
// thesmiths = 0, //史密斯一家
|
||||||
|
// retrocharm, //复古魅力
|
||||||
|
// animalparty, //动物派对
|
||||||
|
// trackhunt, //踪迹追寻
|
||||||
|
// doodledelight, //快乐涂鸦
|
||||||
|
// mysterymeow, //神秘猫咪
|
||||||
|
// tidyup, //整理房间
|
||||||
|
// colorfun, //填色乐趣
|
||||||
|
|
||||||
|
end, //始终放在最后
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2090a55aac6a473cb00da44087c5e38d
|
||||||
|
timeCreated: 1703643978
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class TextureProcess : AssetPostprocessor
|
||||||
|
{
|
||||||
|
private void OnPreprocessTexture()
|
||||||
|
{
|
||||||
|
TextureImporter textureImporter = assetImporter as TextureImporter;
|
||||||
|
if (textureImporter == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//缩略图处理
|
||||||
|
if (textureImporter.assetPath.StartsWith("Assets/AssetRaw/UIRaw/Raw/Thum"))
|
||||||
|
{
|
||||||
|
textureImporter.maxTextureSize = 512;
|
||||||
|
textureImporter.textureType = TextureImporterType.Sprite;
|
||||||
|
textureImporter.textureShape = TextureImporterShape.Texture2D;
|
||||||
|
textureImporter.alphaIsTransparency = false;
|
||||||
|
textureImporter.isReadable = false;
|
||||||
|
textureImporter.mipmapEnabled = false;
|
||||||
|
textureImporter.wrapMode = TextureWrapMode.Clamp;
|
||||||
|
textureImporter.filterMode = FilterMode.Bilinear;
|
||||||
|
textureImporter.SetPlatformTextureSettings(GetAndroidTextureSettings(TextureImporterFormat.ASTC_6x6, 512));
|
||||||
|
textureImporter.SetPlatformTextureSettings(GetiOSTextureSettings(TextureImporterFormat.ASTC_6x6, 512));
|
||||||
|
}
|
||||||
|
//关卡图处理
|
||||||
|
else if (textureImporter.assetPath.StartsWith("Assets/AssetRaw/UIRaw/Raw/Level"))
|
||||||
|
{
|
||||||
|
if (textureImporter.name.Contains("_base"))
|
||||||
|
{
|
||||||
|
textureImporter.textureType = TextureImporterType.Sprite;
|
||||||
|
textureImporter.textureShape = TextureImporterShape.Texture2D;
|
||||||
|
textureImporter.alphaIsTransparency = false;
|
||||||
|
textureImporter.isReadable = false;
|
||||||
|
textureImporter.mipmapEnabled = false;
|
||||||
|
textureImporter.wrapMode = TextureWrapMode.Clamp;
|
||||||
|
textureImporter.filterMode = FilterMode.Bilinear;
|
||||||
|
textureImporter.SetPlatformTextureSettings(GetAndroidTextureSettings(TextureImporterFormat.ASTC_6x6,
|
||||||
|
4096));
|
||||||
|
textureImporter.SetPlatformTextureSettings(GetiOSTextureSettings(TextureImporterFormat.ASTC_6x6));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textureImporter.textureType = TextureImporterType.Sprite;
|
||||||
|
textureImporter.textureShape = TextureImporterShape.Texture2D;
|
||||||
|
textureImporter.alphaIsTransparency = true;
|
||||||
|
textureImporter.isReadable = false;
|
||||||
|
textureImporter.mipmapEnabled = false;
|
||||||
|
textureImporter.wrapMode = TextureWrapMode.Clamp;
|
||||||
|
textureImporter.filterMode = FilterMode.Bilinear;
|
||||||
|
textureImporter.SetPlatformTextureSettings(GetAndroidTextureSettings(TextureImporterFormat.ASTC_6x6));
|
||||||
|
textureImporter.SetPlatformTextureSettings(GetiOSTextureSettings(TextureImporterFormat.ASTC_6x6));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextureImporterPlatformSettings GetAndroidTextureSettings(TextureImporterFormat format, int size = 2048)
|
||||||
|
{
|
||||||
|
TextureImporterPlatformSettings textureImporter = new TextureImporterPlatformSettings();
|
||||||
|
textureImporter.name = "Android";
|
||||||
|
textureImporter.maxTextureSize = size;
|
||||||
|
textureImporter.format = format;
|
||||||
|
textureImporter.overridden = true;
|
||||||
|
textureImporter.textureCompression = TextureImporterCompression.Compressed;
|
||||||
|
return textureImporter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextureImporterPlatformSettings GetiOSTextureSettings(TextureImporterFormat format, int size = 2048)
|
||||||
|
{
|
||||||
|
TextureImporterPlatformSettings textureImporter = new TextureImporterPlatformSettings();
|
||||||
|
textureImporter.name = "iPhone";
|
||||||
|
textureImporter.maxTextureSize = size;
|
||||||
|
textureImporter.format = format;
|
||||||
|
textureImporter.overridden = true;
|
||||||
|
textureImporter.textureCompression = TextureImporterCompression.Compressed;
|
||||||
|
return textureImporter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f1edd427ad4e459c9a855d93bfd17358
|
||||||
|
timeCreated: 1703641976
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9859ae1fa2f2c47b7bcf57daddd8f9c5
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,350 @@
|
||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 2f0b0c553be8edd4682e9180fdd13e37, type: 3}
|
||||||
|
m_Name: I2Languages
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
mSource:
|
||||||
|
UserAgreesToHaveItOnTheScene: 0
|
||||||
|
UserAgreesToHaveItInsideThePluginsFolder: 0
|
||||||
|
GoogleLiveSyncIsUptoDate: 1
|
||||||
|
mTerms:
|
||||||
|
- Term: test
|
||||||
|
TermType: 0
|
||||||
|
Description:
|
||||||
|
Languages:
|
||||||
|
- Test
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
Flags: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
Languages_Touch: []
|
||||||
|
CaseInsensitiveTerms: 0
|
||||||
|
OnMissingTranslation: 1
|
||||||
|
mTerm_AppName:
|
||||||
|
mLanguages:
|
||||||
|
- Name: English
|
||||||
|
Code: en
|
||||||
|
Flags: 0
|
||||||
|
- Name: Afrikaans
|
||||||
|
Code: af
|
||||||
|
Flags: 0
|
||||||
|
- Name: Amharic
|
||||||
|
Code: am
|
||||||
|
Flags: 0
|
||||||
|
- Name: Arabic
|
||||||
|
Code: ar
|
||||||
|
Flags: 0
|
||||||
|
- Name: Azerbaijani
|
||||||
|
Code: az
|
||||||
|
Flags: 0
|
||||||
|
- Name: Belarusian
|
||||||
|
Code: be
|
||||||
|
Flags: 0
|
||||||
|
- Name: Bulgariaa
|
||||||
|
Code: bg
|
||||||
|
Flags: 0
|
||||||
|
- Name: Bengali
|
||||||
|
Code: bn
|
||||||
|
Flags: 0
|
||||||
|
- Name: Catalan
|
||||||
|
Code: ca
|
||||||
|
Flags: 0
|
||||||
|
- Name: Czech
|
||||||
|
Code: cs
|
||||||
|
Flags: 0
|
||||||
|
- Name: Danish
|
||||||
|
Code: da
|
||||||
|
Flags: 0
|
||||||
|
- Name: German
|
||||||
|
Code: de-DE
|
||||||
|
Flags: 0
|
||||||
|
- Name: Greek
|
||||||
|
Code: el
|
||||||
|
Flags: 0
|
||||||
|
- Name: Spanish (Spain)
|
||||||
|
Code: es-ES
|
||||||
|
Flags: 0
|
||||||
|
- Name: Spanish (United States)
|
||||||
|
Code: es-US
|
||||||
|
Flags: 0
|
||||||
|
- Name: Estonian
|
||||||
|
Code: et
|
||||||
|
Flags: 0
|
||||||
|
- Name: Basque [eu-ES]
|
||||||
|
Code: eu-ES
|
||||||
|
Flags: 0
|
||||||
|
- Name: Persian
|
||||||
|
Code: fa
|
||||||
|
Flags: 0
|
||||||
|
- Name: Finnish
|
||||||
|
Code: fi
|
||||||
|
Flags: 0
|
||||||
|
- Name: French (Canada)
|
||||||
|
Code: fr-CA
|
||||||
|
Flags: 0
|
||||||
|
- Name: French (France)
|
||||||
|
Code: fr-FR
|
||||||
|
Flags: 0
|
||||||
|
- Name: Galician [gl-ES]
|
||||||
|
Code: gl-ES
|
||||||
|
Flags: 0
|
||||||
|
- Name: Gujarati
|
||||||
|
Code: gu
|
||||||
|
Flags: 0
|
||||||
|
- Name: Hebrew
|
||||||
|
Code: he
|
||||||
|
Flags: 0
|
||||||
|
- Name: Hindi
|
||||||
|
Code: hi
|
||||||
|
Flags: 0
|
||||||
|
- Name: Croatian
|
||||||
|
Code: hr
|
||||||
|
Flags: 0
|
||||||
|
- Name: Hungarian
|
||||||
|
Code: hu
|
||||||
|
Flags: 0
|
||||||
|
- Name: Armenian
|
||||||
|
Code: hy
|
||||||
|
Flags: 0
|
||||||
|
- Name: Indonesian
|
||||||
|
Code: id
|
||||||
|
Flags: 0
|
||||||
|
- Name: Icelandic
|
||||||
|
Code: is
|
||||||
|
Flags: 0
|
||||||
|
- Name: Italian
|
||||||
|
Code: it-IT
|
||||||
|
Flags: 0
|
||||||
|
- Name: Japanese
|
||||||
|
Code: ja
|
||||||
|
Flags: 0
|
||||||
|
- Name: Georgian
|
||||||
|
Code: ka
|
||||||
|
Flags: 0
|
||||||
|
- Name: Kazakh
|
||||||
|
Code: kk
|
||||||
|
Flags: 0
|
||||||
|
- Name: Khmer
|
||||||
|
Code: km
|
||||||
|
Flags: 0
|
||||||
|
- Name: Kannada
|
||||||
|
Code: kn
|
||||||
|
Flags: 0
|
||||||
|
- Name: Korean
|
||||||
|
Code: ko
|
||||||
|
Flags: 0
|
||||||
|
- Name: Kyrgyz
|
||||||
|
Code: ky
|
||||||
|
Flags: 0
|
||||||
|
- Name: Lao
|
||||||
|
Code: lo
|
||||||
|
Flags: 0
|
||||||
|
- Name: Lithuanian
|
||||||
|
Code: lt
|
||||||
|
Flags: 0
|
||||||
|
- Name: Latvian
|
||||||
|
Code: lv
|
||||||
|
Flags: 0
|
||||||
|
- Name: Macedonian
|
||||||
|
Code: mk
|
||||||
|
Flags: 0
|
||||||
|
- Name: Malayalam
|
||||||
|
Code: ml
|
||||||
|
Flags: 0
|
||||||
|
- Name: Mongolian
|
||||||
|
Code: mn
|
||||||
|
Flags: 0
|
||||||
|
- Name: Marathi
|
||||||
|
Code: mr
|
||||||
|
Flags: 0
|
||||||
|
- Name: Malay (Malaysia)
|
||||||
|
Code: ms-MY
|
||||||
|
Flags: 0
|
||||||
|
- Name: Malay
|
||||||
|
Code: ms
|
||||||
|
Flags: 0
|
||||||
|
- Name: Burmese
|
||||||
|
Code: my
|
||||||
|
Flags: 0
|
||||||
|
- Name: Norwegian
|
||||||
|
Code: nb
|
||||||
|
Flags: 0
|
||||||
|
- Name: Nepali
|
||||||
|
Code: ne
|
||||||
|
Flags: 0
|
||||||
|
- Name: Dutch
|
||||||
|
Code: nl-NL
|
||||||
|
Flags: 0
|
||||||
|
- Name: Punjabi
|
||||||
|
Code: pa
|
||||||
|
Flags: 0
|
||||||
|
- Name: Polish
|
||||||
|
Code: pl
|
||||||
|
Flags: 0
|
||||||
|
- Name: Portuguese (Brazil)
|
||||||
|
Code: pt-BR
|
||||||
|
Flags: 0
|
||||||
|
- Name: Portuguese (Portugal)
|
||||||
|
Code: pt-PT
|
||||||
|
Flags: 0
|
||||||
|
- Name: Romanian
|
||||||
|
Code: ro
|
||||||
|
Flags: 0
|
||||||
|
- Name: Russian
|
||||||
|
Code: ru
|
||||||
|
Flags: 0
|
||||||
|
- Name: Sinhala
|
||||||
|
Code: si
|
||||||
|
Flags: 0
|
||||||
|
- Name: Slovak
|
||||||
|
Code: sk
|
||||||
|
Flags: 0
|
||||||
|
- Name: Slovenian
|
||||||
|
Code: sl
|
||||||
|
Flags: 0
|
||||||
|
- Name: Albanian
|
||||||
|
Code: sq
|
||||||
|
Flags: 0
|
||||||
|
- Name: Serbian
|
||||||
|
Code: sr
|
||||||
|
Flags: 0
|
||||||
|
- Name: Swedish
|
||||||
|
Code: sv-SE
|
||||||
|
Flags: 0
|
||||||
|
- Name: Swahili
|
||||||
|
Code: sw
|
||||||
|
Flags: 0
|
||||||
|
- Name: Tamil
|
||||||
|
Code: ta
|
||||||
|
Flags: 0
|
||||||
|
- Name: Telugu
|
||||||
|
Code: te
|
||||||
|
Flags: 0
|
||||||
|
- Name: Thai
|
||||||
|
Code: th
|
||||||
|
Flags: 0
|
||||||
|
- Name: Tagalog
|
||||||
|
Code: tl
|
||||||
|
Flags: 0
|
||||||
|
- Name: Turkish
|
||||||
|
Code: tr
|
||||||
|
Flags: 0
|
||||||
|
- Name: Ukrainian
|
||||||
|
Code: uk
|
||||||
|
Flags: 0
|
||||||
|
- Name: Urdu
|
||||||
|
Code: ur
|
||||||
|
Flags: 0
|
||||||
|
- Name: Vietnamese
|
||||||
|
Code: vi
|
||||||
|
Flags: 0
|
||||||
|
- Name: Chinese (Simplified)
|
||||||
|
Code: zh-CN
|
||||||
|
Flags: 0
|
||||||
|
- Name: Chinese (Hong Kong)
|
||||||
|
Code: zh-HK
|
||||||
|
Flags: 0
|
||||||
|
- Name: Chinese (Traditional)
|
||||||
|
Code: zh-TW
|
||||||
|
Flags: 0
|
||||||
|
- Name: Zulu
|
||||||
|
Code: zu
|
||||||
|
Flags: 0
|
||||||
|
IgnoreDeviceLanguage: 0
|
||||||
|
_AllowUnloadingLanguages: 0
|
||||||
|
Google_WebServiceURL:
|
||||||
|
Google_SpreadsheetKey:
|
||||||
|
Google_SpreadsheetName:
|
||||||
|
Google_LastUpdatedVersion:
|
||||||
|
Google_Password: change_this
|
||||||
|
GoogleUpdateFrequency: 3
|
||||||
|
GoogleInEditorCheckFrequency: 2
|
||||||
|
GoogleUpdateSynchronization: 1
|
||||||
|
GoogleUpdateDelay: 0
|
||||||
|
Assets: []
|
||||||
|
Spreadsheet_LocalFileName:
|
||||||
|
Spreadsheet_LocalCSVSeparator: ','
|
||||||
|
Spreadsheet_LocalCSVEncoding: utf-8
|
||||||
|
Spreadsheet_SpecializationAsRows: 1
|
||||||
|
Spreadsheet_SortRows: 1
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f4a3e18dc695146a5a8f27c16a4b7e9c
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 5bd1afdce9715f84eb4cbc901922afc2, type: 3}
|
||||||
|
m_Name: YooAssetSettings
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
ManifestFileName: PackageManifest
|
||||||
|
DefaultYooFolderName: yoo
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9a224b3ff275d4acc87b15420b9f2b44
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a5811114ae8414c40813b7de0df8375e
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!29 &1
|
||||||
|
OcclusionCullingSettings:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_OcclusionBakeSettings:
|
||||||
|
smallestOccluder: 5
|
||||||
|
smallestHole: 0.25
|
||||||
|
backfaceThreshold: 100
|
||||||
|
m_SceneGUID: 00000000000000000000000000000000
|
||||||
|
m_OcclusionCullingData: {fileID: 0}
|
||||||
|
--- !u!104 &2
|
||||||
|
RenderSettings:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 9
|
||||||
|
m_Fog: 0
|
||||||
|
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
|
||||||
|
m_FogMode: 3
|
||||||
|
m_FogDensity: 0.01
|
||||||
|
m_LinearFogStart: 0
|
||||||
|
m_LinearFogEnd: 300
|
||||||
|
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
|
||||||
|
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
|
||||||
|
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
|
||||||
|
m_AmbientIntensity: 1
|
||||||
|
m_AmbientMode: 3
|
||||||
|
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
|
||||||
|
m_SkyboxMaterial: {fileID: 0}
|
||||||
|
m_HaloStrength: 0.5
|
||||||
|
m_FlareStrength: 1
|
||||||
|
m_FlareFadeSpeed: 3
|
||||||
|
m_HaloTexture: {fileID: 0}
|
||||||
|
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
m_DefaultReflectionMode: 0
|
||||||
|
m_DefaultReflectionResolution: 128
|
||||||
|
m_ReflectionBounces: 1
|
||||||
|
m_ReflectionIntensity: 1
|
||||||
|
m_CustomReflection: {fileID: 0}
|
||||||
|
m_Sun: {fileID: 0}
|
||||||
|
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
|
||||||
|
m_UseRadianceAmbientProbe: 0
|
||||||
|
--- !u!157 &3
|
||||||
|
LightmapSettings:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 12
|
||||||
|
m_GIWorkflowMode: 1
|
||||||
|
m_GISettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_BounceScale: 1
|
||||||
|
m_IndirectOutputScale: 1
|
||||||
|
m_AlbedoBoost: 1
|
||||||
|
m_EnvironmentLightingMode: 0
|
||||||
|
m_EnableBakedLightmaps: 0
|
||||||
|
m_EnableRealtimeLightmaps: 0
|
||||||
|
m_LightmapEditorSettings:
|
||||||
|
serializedVersion: 12
|
||||||
|
m_Resolution: 2
|
||||||
|
m_BakeResolution: 40
|
||||||
|
m_AtlasSize: 1024
|
||||||
|
m_AO: 0
|
||||||
|
m_AOMaxDistance: 1
|
||||||
|
m_CompAOExponent: 1
|
||||||
|
m_CompAOExponentDirect: 0
|
||||||
|
m_ExtractAmbientOcclusion: 0
|
||||||
|
m_Padding: 2
|
||||||
|
m_LightmapParameters: {fileID: 0}
|
||||||
|
m_LightmapsBakeMode: 1
|
||||||
|
m_TextureCompression: 1
|
||||||
|
m_FinalGather: 0
|
||||||
|
m_FinalGatherFiltering: 1
|
||||||
|
m_FinalGatherRayCount: 256
|
||||||
|
m_ReflectionCompression: 2
|
||||||
|
m_MixedBakeMode: 2
|
||||||
|
m_BakeBackend: 0
|
||||||
|
m_PVRSampling: 1
|
||||||
|
m_PVRDirectSampleCount: 32
|
||||||
|
m_PVRSampleCount: 500
|
||||||
|
m_PVRBounces: 2
|
||||||
|
m_PVREnvironmentSampleCount: 500
|
||||||
|
m_PVREnvironmentReferencePointCount: 2048
|
||||||
|
m_PVRFilteringMode: 2
|
||||||
|
m_PVRDenoiserTypeDirect: 0
|
||||||
|
m_PVRDenoiserTypeIndirect: 0
|
||||||
|
m_PVRDenoiserTypeAO: 0
|
||||||
|
m_PVRFilterTypeDirect: 0
|
||||||
|
m_PVRFilterTypeIndirect: 0
|
||||||
|
m_PVRFilterTypeAO: 0
|
||||||
|
m_PVREnvironmentMIS: 0
|
||||||
|
m_PVRCulling: 1
|
||||||
|
m_PVRFilteringGaussRadiusDirect: 1
|
||||||
|
m_PVRFilteringGaussRadiusIndirect: 5
|
||||||
|
m_PVRFilteringGaussRadiusAO: 2
|
||||||
|
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
||||||
|
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
||||||
|
m_PVRFilteringAtrousPositionSigmaAO: 1
|
||||||
|
m_ExportTrainingData: 0
|
||||||
|
m_TrainingDataDestination: TrainingData
|
||||||
|
m_LightProbeSampleCountMultiplier: 4
|
||||||
|
m_LightingDataAsset: {fileID: 0}
|
||||||
|
m_LightingSettings: {fileID: 0}
|
||||||
|
--- !u!196 &4
|
||||||
|
NavMeshSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_BuildSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
agentTypeID: 0
|
||||||
|
agentRadius: 0.5
|
||||||
|
agentHeight: 2
|
||||||
|
agentSlope: 45
|
||||||
|
agentClimb: 0.4
|
||||||
|
ledgeDropHeight: 0
|
||||||
|
maxJumpAcrossDistance: 0
|
||||||
|
minRegionArea: 2
|
||||||
|
manualCellSize: 0
|
||||||
|
cellSize: 0.16666667
|
||||||
|
manualTileSize: 0
|
||||||
|
tileSize: 256
|
||||||
|
accuratePlacement: 0
|
||||||
|
maxJobWorkers: 0
|
||||||
|
preserveTilesOutsideBounds: 0
|
||||||
|
debug:
|
||||||
|
m_Flags: 0
|
||||||
|
m_NavMeshData: {fileID: 0}
|
||||||
|
--- !u!1 &519420028
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 519420032}
|
||||||
|
- component: {fileID: 519420031}
|
||||||
|
- component: {fileID: 519420029}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Main Camera
|
||||||
|
m_TagString: MainCamera
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!81 &519420029
|
||||||
|
AudioListener:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 519420028}
|
||||||
|
m_Enabled: 1
|
||||||
|
--- !u!20 &519420031
|
||||||
|
Camera:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 519420028}
|
||||||
|
m_Enabled: 1
|
||||||
|
serializedVersion: 2
|
||||||
|
m_ClearFlags: 2
|
||||||
|
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
|
||||||
|
m_projectionMatrixMode: 1
|
||||||
|
m_GateFitMode: 2
|
||||||
|
m_FOVAxisMode: 0
|
||||||
|
m_SensorSize: {x: 36, y: 24}
|
||||||
|
m_LensShift: {x: 0, y: 0}
|
||||||
|
m_FocalLength: 50
|
||||||
|
m_NormalizedViewPortRect:
|
||||||
|
serializedVersion: 2
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
near clip plane: 0.3
|
||||||
|
far clip plane: 1000
|
||||||
|
field of view: 60
|
||||||
|
orthographic: 1
|
||||||
|
orthographic size: 5
|
||||||
|
m_Depth: -1
|
||||||
|
m_CullingMask:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 4294967295
|
||||||
|
m_RenderingPath: -1
|
||||||
|
m_TargetTexture: {fileID: 0}
|
||||||
|
m_TargetDisplay: 0
|
||||||
|
m_TargetEye: 0
|
||||||
|
m_HDR: 1
|
||||||
|
m_AllowMSAA: 0
|
||||||
|
m_AllowDynamicResolution: 0
|
||||||
|
m_ForceIntoRT: 0
|
||||||
|
m_OcclusionCulling: 0
|
||||||
|
m_StereoConvergence: 10
|
||||||
|
m_StereoSeparation: 0.022
|
||||||
|
--- !u!4 &519420032
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 519420028}
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: -10}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_RootOrder: 0
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2cda990e2423bbf4892e6590ba056729
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3ac1aba04265f9143957a5b474de973d
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: db680274cf006c548abff57b7e1894b4
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ac093515ae764b94aa07be91d4ba978b
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1fdecc5500229d44887425ce619352fc
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class AssetBundleBuilder
|
||||||
|
{
|
||||||
|
private readonly BuildContext _buildContext = new BuildContext();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建资源包
|
||||||
|
/// </summary>
|
||||||
|
public BuildResult Run(BuildParameters buildParameters, List<IBuildTask> buildPipeline)
|
||||||
|
{
|
||||||
|
// 检测构建参数是否为空
|
||||||
|
if (buildParameters == null)
|
||||||
|
throw new Exception($"{nameof(buildParameters)} is null !");
|
||||||
|
|
||||||
|
// 检测构建参数是否为空
|
||||||
|
if (buildPipeline.Count == 0)
|
||||||
|
throw new Exception($"Build pipeline is empty !");
|
||||||
|
|
||||||
|
// 清空旧数据
|
||||||
|
_buildContext.ClearAllContext();
|
||||||
|
|
||||||
|
// 构建参数
|
||||||
|
var buildParametersContext = new BuildParametersContext(buildParameters);
|
||||||
|
_buildContext.SetContextObject(buildParametersContext);
|
||||||
|
|
||||||
|
// 初始化日志
|
||||||
|
BuildLogger.InitLogger(buildParameters.EnableLog);
|
||||||
|
|
||||||
|
// 执行构建流程
|
||||||
|
var buildResult = BuildRunner.Run(buildPipeline, _buildContext);
|
||||||
|
if (buildResult.Success)
|
||||||
|
{
|
||||||
|
buildResult.OutputPackageDirectory = buildParametersContext.GetPackageOutputDirectory();
|
||||||
|
BuildLogger.Log($"{buildParameters.BuildMode} pipeline build succeed !");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BuildLogger.Warning($"{buildParameters.BuildMode} pipeline build failed !");
|
||||||
|
BuildLogger.Error($"Build task failed : {buildResult.FailedTask}");
|
||||||
|
BuildLogger.Error(buildResult.ErrorInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buildResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建资源包
|
||||||
|
/// </summary>
|
||||||
|
public BuildResult Run(BuildParameters buildParameters)
|
||||||
|
{
|
||||||
|
var buildPipeline = GetDefaultBuildPipeline(buildParameters.BuildPipeline);
|
||||||
|
return Run(buildParameters, buildPipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取默认的构建流程
|
||||||
|
/// </summary>
|
||||||
|
private List<IBuildTask> GetDefaultBuildPipeline(EBuildPipeline buildPipeline)
|
||||||
|
{
|
||||||
|
// 获取任务节点的属性集合
|
||||||
|
if (buildPipeline == EBuildPipeline.BuiltinBuildPipeline)
|
||||||
|
{
|
||||||
|
List<IBuildTask> pipeline = new List<IBuildTask>
|
||||||
|
{
|
||||||
|
new TaskPrepare(), //前期准备工作
|
||||||
|
new TaskGetBuildMap(), //获取构建列表
|
||||||
|
new TaskBuilding(), //开始执行构建
|
||||||
|
new TaskCopyRawFile(), //拷贝原生文件
|
||||||
|
new TaskVerifyBuildResult(), //验证构建结果
|
||||||
|
new TaskEncryption(), //加密资源文件
|
||||||
|
new TaskUpdateBundleInfo(), //更新资源包信息
|
||||||
|
new TaskCreateManifest(), //创建清单文件
|
||||||
|
new TaskCreateReport(), //创建报告文件
|
||||||
|
new TaskCreatePackage(), //制作包裹
|
||||||
|
new TaskCopyBuildinFiles(), //拷贝内置文件
|
||||||
|
};
|
||||||
|
return pipeline;
|
||||||
|
}
|
||||||
|
else if (buildPipeline == EBuildPipeline.ScriptableBuildPipeline)
|
||||||
|
{
|
||||||
|
List<IBuildTask> pipeline = new List<IBuildTask>
|
||||||
|
{
|
||||||
|
new TaskPrepare(), //前期准备工作
|
||||||
|
new TaskGetBuildMap(), //获取构建列表
|
||||||
|
new TaskBuilding_SBP(), //开始执行构建
|
||||||
|
new TaskCopyRawFile(), //拷贝原生文件
|
||||||
|
new TaskVerifyBuildResult_SBP(), //验证构建结果
|
||||||
|
new TaskEncryption(), //加密资源文件
|
||||||
|
new TaskUpdateBundleInfo(), //更新补丁信息
|
||||||
|
new TaskCreateManifest(), //创建清单文件
|
||||||
|
new TaskCreateReport(), //创建报告文件
|
||||||
|
new TaskCreatePackage(), //制作补丁包
|
||||||
|
new TaskCopyBuildinFiles(), //拷贝内置文件
|
||||||
|
};
|
||||||
|
return pipeline;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: de7563040250b4e4a835d1fc90238e38
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public static class AssetBundleBuilderHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取默认的输出根路录
|
||||||
|
/// </summary>
|
||||||
|
public static string GetDefaultBuildOutputRoot()
|
||||||
|
{
|
||||||
|
string projectPath = EditorTools.GetProjectPath();
|
||||||
|
return $"{projectPath}/Bundles";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取流文件夹路径
|
||||||
|
/// </summary>
|
||||||
|
public static string GetDefaultStreamingAssetsRoot()
|
||||||
|
{
|
||||||
|
return $"{Application.dataPath}/StreamingAssets/{YooAssetSettingsData.Setting.DefaultYooFolderName}/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f48abdec05f0dbe438a83e181fe6bc93
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[CreateAssetMenu(fileName = "AssetBundleBuilderSetting", menuName = "YooAsset/Create AssetBundle Builder Settings")]
|
||||||
|
public class AssetBundleBuilderSetting : ScriptableObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 构建管线
|
||||||
|
/// </summary>
|
||||||
|
public EBuildPipeline BuildPipeline = EBuildPipeline.BuiltinBuildPipeline;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建模式
|
||||||
|
/// </summary>
|
||||||
|
public EBuildMode BuildMode = EBuildMode.ForceRebuild;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建的包裹名称
|
||||||
|
/// </summary>
|
||||||
|
public string BuildPackage = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩方式
|
||||||
|
/// </summary>
|
||||||
|
public ECompressOption CompressOption = ECompressOption.LZ4;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 输出文件名称样式
|
||||||
|
/// </summary>
|
||||||
|
public EOutputNameStyle OutputNameStyle = EOutputNameStyle.HashName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 首包资源文件的拷贝方式
|
||||||
|
/// </summary>
|
||||||
|
public ECopyBuildinFileOption CopyBuildinFileOption = ECopyBuildinFileOption.None;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 首包资源文件的标签集合
|
||||||
|
/// </summary>
|
||||||
|
public string CopyBuildinFileTags = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加密类名称
|
||||||
|
/// </summary>
|
||||||
|
public string EncyptionClassName = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 09788b4733bab2d4792fdd5d28e7653c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class AssetBundleBuilderSettingData
|
||||||
|
{
|
||||||
|
private static AssetBundleBuilderSetting _setting = null;
|
||||||
|
public static AssetBundleBuilderSetting Setting
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_setting == null)
|
||||||
|
LoadSettingData();
|
||||||
|
return _setting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置数据是否被修改
|
||||||
|
/// </summary>
|
||||||
|
public static bool IsDirty { set; get; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加载配置文件
|
||||||
|
/// </summary>
|
||||||
|
private static void LoadSettingData()
|
||||||
|
{
|
||||||
|
_setting = SettingLoader.LoadSettingData<AssetBundleBuilderSetting>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 存储文件
|
||||||
|
/// </summary>
|
||||||
|
public static void SaveFile()
|
||||||
|
{
|
||||||
|
if (Setting != null)
|
||||||
|
{
|
||||||
|
IsDirty = false;
|
||||||
|
EditorUtility.SetDirty(Setting);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
Debug.Log($"{nameof(AssetBundleBuilderSetting)}.asset is saved!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 24698266f028e4a47bb88f091fd64547
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,359 @@
|
||||||
|
#if UNITY_2019_4_OR_NEWER
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor.UIElements;
|
||||||
|
using UnityEngine.UIElements;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class AssetBundleBuilderWindow : EditorWindow
|
||||||
|
{
|
||||||
|
[MenuItem("YooAsset/AssetBundle Builder", false, 102)]
|
||||||
|
public static void OpenWindow()
|
||||||
|
{
|
||||||
|
AssetBundleBuilderWindow window = GetWindow<AssetBundleBuilderWindow>("资源包构建工具", true, WindowsDefine.DockedWindowTypes);
|
||||||
|
window.minSize = new Vector2(800, 600);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BuildTarget _buildTarget;
|
||||||
|
private List<Type> _encryptionServicesClassTypes;
|
||||||
|
private List<string> _encryptionServicesClassNames;
|
||||||
|
private List<string> _buildPackageNames;
|
||||||
|
|
||||||
|
private Button _saveButton;
|
||||||
|
private TextField _buildOutputField;
|
||||||
|
private EnumField _buildPipelineField;
|
||||||
|
private EnumField _buildModeField;
|
||||||
|
private TextField _buildVersionField;
|
||||||
|
private PopupField<string> _buildPackageField;
|
||||||
|
private PopupField<string> _encryptionField;
|
||||||
|
private EnumField _compressionField;
|
||||||
|
private EnumField _outputNameStyleField;
|
||||||
|
private EnumField _copyBuildinFileOptionField;
|
||||||
|
private TextField _copyBuildinFileTagsField;
|
||||||
|
|
||||||
|
public void CreateGUI()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
VisualElement root = this.rootVisualElement;
|
||||||
|
|
||||||
|
// 加载布局文件
|
||||||
|
var visualAsset = UxmlLoader.LoadWindowUXML<AssetBundleBuilderWindow>();
|
||||||
|
if (visualAsset == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
visualAsset.CloneTree(root);
|
||||||
|
|
||||||
|
// 配置保存按钮
|
||||||
|
_saveButton = root.Q<Button>("SaveButton");
|
||||||
|
_saveButton.clicked += SaveBtn_clicked;
|
||||||
|
|
||||||
|
// 构建平台
|
||||||
|
_buildTarget = EditorUserBuildSettings.activeBuildTarget;
|
||||||
|
|
||||||
|
// 包裹名称列表
|
||||||
|
_buildPackageNames = GetBuildPackageNames();
|
||||||
|
|
||||||
|
// 加密服务类
|
||||||
|
_encryptionServicesClassTypes = GetEncryptionServicesClassTypes();
|
||||||
|
_encryptionServicesClassNames = _encryptionServicesClassTypes.Select(t => t.Name).ToList();
|
||||||
|
|
||||||
|
// 输出目录
|
||||||
|
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
|
||||||
|
_buildOutputField = root.Q<TextField>("BuildOutput");
|
||||||
|
_buildOutputField.SetValueWithoutNotify(defaultOutputRoot);
|
||||||
|
_buildOutputField.SetEnabled(false);
|
||||||
|
|
||||||
|
// 构建管线
|
||||||
|
_buildPipelineField = root.Q<EnumField>("BuildPipeline");
|
||||||
|
_buildPipelineField.Init(AssetBundleBuilderSettingData.Setting.BuildPipeline);
|
||||||
|
_buildPipelineField.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.BuildPipeline);
|
||||||
|
_buildPipelineField.style.width = 350;
|
||||||
|
_buildPipelineField.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
AssetBundleBuilderSettingData.IsDirty = true;
|
||||||
|
AssetBundleBuilderSettingData.Setting.BuildPipeline = (EBuildPipeline)_buildPipelineField.value;
|
||||||
|
RefreshWindow();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 构建模式
|
||||||
|
_buildModeField = root.Q<EnumField>("BuildMode");
|
||||||
|
_buildModeField.Init(AssetBundleBuilderSettingData.Setting.BuildMode);
|
||||||
|
_buildModeField.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.BuildMode);
|
||||||
|
_buildModeField.style.width = 350;
|
||||||
|
_buildModeField.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
AssetBundleBuilderSettingData.IsDirty = true;
|
||||||
|
AssetBundleBuilderSettingData.Setting.BuildMode = (EBuildMode)_buildModeField.value;
|
||||||
|
RefreshWindow();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 构建版本
|
||||||
|
_buildVersionField = root.Q<TextField>("BuildVersion");
|
||||||
|
_buildVersionField.SetValueWithoutNotify(GetBuildPackageVersion());
|
||||||
|
|
||||||
|
// 构建包裹
|
||||||
|
var buildPackageContainer = root.Q("BuildPackageContainer");
|
||||||
|
if (_buildPackageNames.Count > 0)
|
||||||
|
{
|
||||||
|
int defaultIndex = GetDefaultPackageIndex(AssetBundleBuilderSettingData.Setting.BuildPackage);
|
||||||
|
_buildPackageField = new PopupField<string>(_buildPackageNames, defaultIndex);
|
||||||
|
_buildPackageField.label = "Build Package";
|
||||||
|
_buildPackageField.style.width = 350;
|
||||||
|
_buildPackageField.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
AssetBundleBuilderSettingData.IsDirty = true;
|
||||||
|
AssetBundleBuilderSettingData.Setting.BuildPackage = _buildPackageField.value;
|
||||||
|
});
|
||||||
|
buildPackageContainer.Add(_buildPackageField);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_buildPackageField = new PopupField<string>();
|
||||||
|
_buildPackageField.label = "Build Package";
|
||||||
|
_buildPackageField.style.width = 350;
|
||||||
|
buildPackageContainer.Add(_buildPackageField);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加密方法
|
||||||
|
var encryptionContainer = root.Q("EncryptionContainer");
|
||||||
|
if (_encryptionServicesClassNames.Count > 0)
|
||||||
|
{
|
||||||
|
int defaultIndex = GetDefaultEncryptionIndex(AssetBundleBuilderSettingData.Setting.EncyptionClassName);
|
||||||
|
_encryptionField = new PopupField<string>(_encryptionServicesClassNames, defaultIndex);
|
||||||
|
_encryptionField.label = "Encryption";
|
||||||
|
_encryptionField.style.width = 350;
|
||||||
|
_encryptionField.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
AssetBundleBuilderSettingData.IsDirty = true;
|
||||||
|
AssetBundleBuilderSettingData.Setting.EncyptionClassName = _encryptionField.value;
|
||||||
|
});
|
||||||
|
encryptionContainer.Add(_encryptionField);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_encryptionField = new PopupField<string>();
|
||||||
|
_encryptionField.label = "Encryption";
|
||||||
|
_encryptionField.style.width = 350;
|
||||||
|
encryptionContainer.Add(_encryptionField);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 压缩方式选项
|
||||||
|
_compressionField = root.Q<EnumField>("Compression");
|
||||||
|
_compressionField.Init(AssetBundleBuilderSettingData.Setting.CompressOption);
|
||||||
|
_compressionField.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.CompressOption);
|
||||||
|
_compressionField.style.width = 350;
|
||||||
|
_compressionField.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
AssetBundleBuilderSettingData.IsDirty = true;
|
||||||
|
AssetBundleBuilderSettingData.Setting.CompressOption = (ECompressOption)_compressionField.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 输出文件名称样式
|
||||||
|
_outputNameStyleField = root.Q<EnumField>("OutputNameStyle");
|
||||||
|
_outputNameStyleField.Init(AssetBundleBuilderSettingData.Setting.OutputNameStyle);
|
||||||
|
_outputNameStyleField.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.OutputNameStyle);
|
||||||
|
_outputNameStyleField.style.width = 350;
|
||||||
|
_outputNameStyleField.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
AssetBundleBuilderSettingData.IsDirty = true;
|
||||||
|
AssetBundleBuilderSettingData.Setting.OutputNameStyle = (EOutputNameStyle)_outputNameStyleField.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 首包文件拷贝选项
|
||||||
|
_copyBuildinFileOptionField = root.Q<EnumField>("CopyBuildinFileOption");
|
||||||
|
_copyBuildinFileOptionField.Init(AssetBundleBuilderSettingData.Setting.CopyBuildinFileOption);
|
||||||
|
_copyBuildinFileOptionField.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.CopyBuildinFileOption);
|
||||||
|
_copyBuildinFileOptionField.style.width = 350;
|
||||||
|
_copyBuildinFileOptionField.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
AssetBundleBuilderSettingData.IsDirty = true;
|
||||||
|
AssetBundleBuilderSettingData.Setting.CopyBuildinFileOption = (ECopyBuildinFileOption)_copyBuildinFileOptionField.value;
|
||||||
|
RefreshWindow();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 首包文件的资源标签
|
||||||
|
_copyBuildinFileTagsField = root.Q<TextField>("CopyBuildinFileTags");
|
||||||
|
_copyBuildinFileTagsField.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.CopyBuildinFileTags);
|
||||||
|
_copyBuildinFileTagsField.RegisterValueChangedCallback(evt =>
|
||||||
|
{
|
||||||
|
AssetBundleBuilderSettingData.IsDirty = true;
|
||||||
|
AssetBundleBuilderSettingData.Setting.CopyBuildinFileTags = _copyBuildinFileTagsField.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 构建按钮
|
||||||
|
var buildButton = root.Q<Button>("Build");
|
||||||
|
buildButton.clicked += BuildButton_clicked; ;
|
||||||
|
|
||||||
|
RefreshWindow();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogError(e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void OnDestroy()
|
||||||
|
{
|
||||||
|
if (AssetBundleBuilderSettingData.IsDirty)
|
||||||
|
AssetBundleBuilderSettingData.SaveFile();
|
||||||
|
}
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
if (_saveButton != null)
|
||||||
|
{
|
||||||
|
if (AssetBundleBuilderSettingData.IsDirty)
|
||||||
|
{
|
||||||
|
if (_saveButton.enabledSelf == false)
|
||||||
|
_saveButton.SetEnabled(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_saveButton.enabledSelf)
|
||||||
|
_saveButton.SetEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshWindow()
|
||||||
|
{
|
||||||
|
var buildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline;
|
||||||
|
var buildMode = AssetBundleBuilderSettingData.Setting.BuildMode;
|
||||||
|
var copyOption = AssetBundleBuilderSettingData.Setting.CopyBuildinFileOption;
|
||||||
|
bool enableElement = buildMode == EBuildMode.ForceRebuild;
|
||||||
|
bool tagsFiledVisible = copyOption == ECopyBuildinFileOption.ClearAndCopyByTags || copyOption == ECopyBuildinFileOption.OnlyCopyByTags;
|
||||||
|
|
||||||
|
if (buildPipeline == EBuildPipeline.BuiltinBuildPipeline)
|
||||||
|
{
|
||||||
|
_compressionField.SetEnabled(enableElement);
|
||||||
|
_outputNameStyleField.SetEnabled(enableElement);
|
||||||
|
_copyBuildinFileOptionField.SetEnabled(enableElement);
|
||||||
|
_copyBuildinFileTagsField.SetEnabled(enableElement);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_compressionField.SetEnabled(true);
|
||||||
|
_outputNameStyleField.SetEnabled(true);
|
||||||
|
_copyBuildinFileOptionField.SetEnabled(true);
|
||||||
|
_copyBuildinFileTagsField.SetEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
_copyBuildinFileTagsField.visible = tagsFiledVisible;
|
||||||
|
}
|
||||||
|
private void SaveBtn_clicked()
|
||||||
|
{
|
||||||
|
AssetBundleBuilderSettingData.SaveFile();
|
||||||
|
}
|
||||||
|
private void BuildButton_clicked()
|
||||||
|
{
|
||||||
|
var buildMode = AssetBundleBuilderSettingData.Setting.BuildMode;
|
||||||
|
if (EditorUtility.DisplayDialog("提示", $"通过构建模式【{buildMode}】来构建!", "Yes", "No"))
|
||||||
|
{
|
||||||
|
EditorTools.ClearUnityConsole();
|
||||||
|
EditorApplication.delayCall += ExecuteBuild;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning("[Build] 打包已经取消");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行构建
|
||||||
|
/// </summary>
|
||||||
|
private void ExecuteBuild()
|
||||||
|
{
|
||||||
|
BuildParameters buildParameters = new BuildParameters();
|
||||||
|
buildParameters.StreamingAssetsRoot = AssetBundleBuilderHelper.GetDefaultStreamingAssetsRoot();
|
||||||
|
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
|
||||||
|
buildParameters.BuildTarget = _buildTarget;
|
||||||
|
buildParameters.BuildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline;
|
||||||
|
buildParameters.BuildMode = AssetBundleBuilderSettingData.Setting.BuildMode;
|
||||||
|
buildParameters.PackageName = AssetBundleBuilderSettingData.Setting.BuildPackage;
|
||||||
|
buildParameters.PackageVersion = _buildVersionField.value;
|
||||||
|
buildParameters.VerifyBuildingResult = true;
|
||||||
|
buildParameters.SharedPackRule = new ZeroRedundancySharedPackRule();
|
||||||
|
buildParameters.EncryptionServices = CreateEncryptionServicesInstance();
|
||||||
|
buildParameters.CompressOption = AssetBundleBuilderSettingData.Setting.CompressOption;
|
||||||
|
buildParameters.OutputNameStyle = AssetBundleBuilderSettingData.Setting.OutputNameStyle;
|
||||||
|
buildParameters.CopyBuildinFileOption = AssetBundleBuilderSettingData.Setting.CopyBuildinFileOption;
|
||||||
|
buildParameters.CopyBuildinFileTags = AssetBundleBuilderSettingData.Setting.CopyBuildinFileTags;
|
||||||
|
|
||||||
|
if (AssetBundleBuilderSettingData.Setting.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
|
||||||
|
{
|
||||||
|
buildParameters.SBPParameters = new BuildParameters.SBPBuildParameters();
|
||||||
|
buildParameters.SBPParameters.WriteLinkXML = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var builder = new AssetBundleBuilder();
|
||||||
|
var buildResult = builder.Run(buildParameters);
|
||||||
|
if (buildResult.Success)
|
||||||
|
{
|
||||||
|
EditorUtility.RevealInFinder(buildResult.OutputPackageDirectory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建版本相关
|
||||||
|
private string GetBuildPackageVersion()
|
||||||
|
{
|
||||||
|
int totalMinutes = DateTime.Now.Hour * 60 + DateTime.Now.Minute;
|
||||||
|
return DateTime.Now.ToString("yyyy-MM-dd") + "-" + totalMinutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建包裹相关
|
||||||
|
private int GetDefaultPackageIndex(string packageName)
|
||||||
|
{
|
||||||
|
for (int index = 0; index < _buildPackageNames.Count; index++)
|
||||||
|
{
|
||||||
|
if (_buildPackageNames[index] == packageName)
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetBundleBuilderSettingData.IsDirty = true;
|
||||||
|
AssetBundleBuilderSettingData.Setting.BuildPackage = _buildPackageNames[0];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
private List<string> GetBuildPackageNames()
|
||||||
|
{
|
||||||
|
List<string> result = new List<string>();
|
||||||
|
foreach (var package in AssetBundleCollectorSettingData.Setting.Packages)
|
||||||
|
{
|
||||||
|
result.Add(package.PackageName);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加密类相关
|
||||||
|
private int GetDefaultEncryptionIndex(string className)
|
||||||
|
{
|
||||||
|
for (int index = 0; index < _encryptionServicesClassNames.Count; index++)
|
||||||
|
{
|
||||||
|
if (_encryptionServicesClassNames[index] == className)
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetBundleBuilderSettingData.IsDirty = true;
|
||||||
|
AssetBundleBuilderSettingData.Setting.EncyptionClassName = _encryptionServicesClassNames[0];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
private List<Type> GetEncryptionServicesClassTypes()
|
||||||
|
{
|
||||||
|
return EditorTools.GetAssignableTypes(typeof(IEncryptionServices));
|
||||||
|
}
|
||||||
|
private IEncryptionServices CreateEncryptionServicesInstance()
|
||||||
|
{
|
||||||
|
if (_encryptionField.index < 0)
|
||||||
|
return null;
|
||||||
|
var classType = _encryptionServicesClassTypes[_encryptionField.index];
|
||||||
|
return (IEncryptionServices)Activator.CreateInstance(classType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 66e43420e95cd0b4bae8803a31e9817b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
|
||||||
|
<uie:Toolbar name="Toolbar" style="display: flex; flex-direction: row-reverse;">
|
||||||
|
<ui:Button text="Save" display-tooltip-when-elided="true" name="SaveButton" style="background-color: rgb(56, 147, 58);" />
|
||||||
|
</uie:Toolbar>
|
||||||
|
<ui:VisualElement name="BuildContainer">
|
||||||
|
<ui:TextField picking-mode="Ignore" label="Build Output" name="BuildOutput" />
|
||||||
|
<uie:EnumField label="Build Pipeline" name="BuildPipeline" />
|
||||||
|
<uie:EnumField label="Build Mode" name="BuildMode" />
|
||||||
|
<ui:TextField picking-mode="Ignore" label="Build Version" name="BuildVersion" style="width: 350px;" />
|
||||||
|
<ui:VisualElement name="BuildPackageContainer" style="height: 24px;" />
|
||||||
|
<ui:VisualElement name="EncryptionContainer" style="height: 24px;" />
|
||||||
|
<uie:EnumField label="Compression" value="Center" name="Compression" />
|
||||||
|
<uie:EnumField label="Output Name Style" value="Center" name="OutputNameStyle" />
|
||||||
|
<uie:EnumField label="Copy Buildin File Option" value="Center" name="CopyBuildinFileOption" />
|
||||||
|
<ui:TextField picking-mode="Ignore" label="Copy Buildin File Tags" name="CopyBuildinFileTags" />
|
||||||
|
<ui:Button text="构建" display-tooltip-when-elided="true" name="Build" style="height: 50px; background-color: rgb(40, 106, 42); margin-top: 10px;" />
|
||||||
|
</ui:VisualElement>
|
||||||
|
</ui:UXML>
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 28ba29adb4949284e8c48893218b0d9a
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public static class AssetBundleSimulateBuilder
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 模拟构建
|
||||||
|
/// </summary>
|
||||||
|
public static string SimulateBuild(string packageName)
|
||||||
|
{
|
||||||
|
Debug.Log($"Begin to create simulate package : {packageName}");
|
||||||
|
BuildParameters buildParameters = new BuildParameters();
|
||||||
|
buildParameters.StreamingAssetsRoot = AssetBundleBuilderHelper.GetDefaultStreamingAssetsRoot();
|
||||||
|
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
|
||||||
|
buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget;
|
||||||
|
buildParameters.BuildMode = EBuildMode.SimulateBuild;
|
||||||
|
buildParameters.PackageName = packageName;
|
||||||
|
buildParameters.PackageVersion = "Simulate";
|
||||||
|
buildParameters.EnableLog = false;
|
||||||
|
|
||||||
|
AssetBundleBuilder builder = new AssetBundleBuilder();
|
||||||
|
var buildResult = builder.Run(buildParameters);
|
||||||
|
if (buildResult.Success)
|
||||||
|
{
|
||||||
|
string manifestFileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||||
|
string manifestFilePath = $"{buildResult.OutputPackageDirectory}/{manifestFileName}";
|
||||||
|
return manifestFilePath;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f94918fa1ea63c34fa0e49fdad4119cf
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,213 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class BuildAssetInfo
|
||||||
|
{
|
||||||
|
private bool _isAddAssetTags = false;
|
||||||
|
private readonly HashSet<string> _referenceBundleNames = new HashSet<string>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 收集器类型
|
||||||
|
/// </summary>
|
||||||
|
public ECollectorType CollectorType { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源包完整名称
|
||||||
|
/// </summary>
|
||||||
|
public string BundleName { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 可寻址地址
|
||||||
|
/// </summary>
|
||||||
|
public string Address { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源路径
|
||||||
|
/// </summary>
|
||||||
|
public string AssetPath { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源GUID
|
||||||
|
/// </summary>
|
||||||
|
public string AssetGUID { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否为原生资源
|
||||||
|
/// </summary>
|
||||||
|
public bool IsRawAsset { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否为着色器资源
|
||||||
|
/// </summary>
|
||||||
|
public bool IsShaderAsset { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源的分类标签
|
||||||
|
/// </summary>
|
||||||
|
public readonly List<string> AssetTags = new List<string>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源包的分类标签
|
||||||
|
/// </summary>
|
||||||
|
public readonly List<string> BundleTags = new List<string>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 依赖的所有资源
|
||||||
|
/// 注意:包括零依赖资源和冗余资源(资源包名无效)
|
||||||
|
/// </summary>
|
||||||
|
public List<BuildAssetInfo> AllDependAssetInfos { private set; get; }
|
||||||
|
|
||||||
|
|
||||||
|
public BuildAssetInfo(ECollectorType collectorType, string bundleName, string address, string assetPath, bool isRawAsset)
|
||||||
|
{
|
||||||
|
CollectorType = collectorType;
|
||||||
|
BundleName = bundleName;
|
||||||
|
Address = address;
|
||||||
|
AssetPath = assetPath;
|
||||||
|
IsRawAsset = isRawAsset;
|
||||||
|
|
||||||
|
AssetGUID = UnityEditor.AssetDatabase.AssetPathToGUID(assetPath);
|
||||||
|
System.Type assetType = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(assetPath);
|
||||||
|
if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection))
|
||||||
|
IsShaderAsset = true;
|
||||||
|
else
|
||||||
|
IsShaderAsset = false;
|
||||||
|
}
|
||||||
|
public BuildAssetInfo(string assetPath)
|
||||||
|
{
|
||||||
|
CollectorType = ECollectorType.None;
|
||||||
|
Address = string.Empty;
|
||||||
|
AssetPath = assetPath;
|
||||||
|
IsRawAsset = false;
|
||||||
|
|
||||||
|
AssetGUID = UnityEditor.AssetDatabase.AssetPathToGUID(assetPath);
|
||||||
|
System.Type assetType = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(assetPath);
|
||||||
|
if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection))
|
||||||
|
IsShaderAsset = true;
|
||||||
|
else
|
||||||
|
IsShaderAsset = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置所有依赖的资源
|
||||||
|
/// </summary>
|
||||||
|
public void SetAllDependAssetInfos(List<BuildAssetInfo> dependAssetInfos)
|
||||||
|
{
|
||||||
|
if (AllDependAssetInfos != null)
|
||||||
|
throw new System.Exception("Should never get here !");
|
||||||
|
|
||||||
|
AllDependAssetInfos = dependAssetInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加资源的分类标签
|
||||||
|
/// 说明:原始定义的资源分类标签
|
||||||
|
/// </summary>
|
||||||
|
public void AddAssetTags(List<string> tags)
|
||||||
|
{
|
||||||
|
if (_isAddAssetTags)
|
||||||
|
throw new Exception("Should never get here !");
|
||||||
|
_isAddAssetTags = true;
|
||||||
|
|
||||||
|
foreach (var tag in tags)
|
||||||
|
{
|
||||||
|
if (AssetTags.Contains(tag) == false)
|
||||||
|
{
|
||||||
|
AssetTags.Add(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加资源包的分类标签
|
||||||
|
/// 说明:传染算法统计到的分类标签
|
||||||
|
/// </summary>
|
||||||
|
public void AddBundleTags(List<string> tags)
|
||||||
|
{
|
||||||
|
foreach (var tag in tags)
|
||||||
|
{
|
||||||
|
if (BundleTags.Contains(tag) == false)
|
||||||
|
{
|
||||||
|
BundleTags.Add(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源包名是否存在
|
||||||
|
/// </summary>
|
||||||
|
public bool HasBundleName()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(BundleName))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加关联的资源包名称
|
||||||
|
/// </summary>
|
||||||
|
public void AddReferenceBundleName(string bundleName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(bundleName))
|
||||||
|
throw new Exception("Should never get here !");
|
||||||
|
|
||||||
|
if (_referenceBundleNames.Contains(bundleName) == false)
|
||||||
|
_referenceBundleNames.Add(bundleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算共享资源包的完整包名
|
||||||
|
/// </summary>
|
||||||
|
public void CalculateShareBundleName(ISharedPackRule sharedPackRule, bool uniqueBundleName, string packageName, string shadersBundleName)
|
||||||
|
{
|
||||||
|
if (CollectorType != ECollectorType.None)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (IsRawAsset)
|
||||||
|
throw new Exception("Should never get here !");
|
||||||
|
|
||||||
|
if (IsShaderAsset)
|
||||||
|
{
|
||||||
|
BundleName = shadersBundleName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_referenceBundleNames.Count > 1)
|
||||||
|
{
|
||||||
|
PackRuleResult packRuleResult = sharedPackRule.GetPackRuleResult(AssetPath);
|
||||||
|
BundleName = packRuleResult.GetShareBundleName(packageName, uniqueBundleName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 注意:被引用次数小于1的资源不需要设置资源包名称
|
||||||
|
BundleName = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 判断是否为冗余资源
|
||||||
|
/// </summary>
|
||||||
|
public bool IsRedundancyAsset()
|
||||||
|
{
|
||||||
|
if (HasBundleName())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return _referenceBundleNames.Count > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取关联资源包的数量
|
||||||
|
/// </summary>
|
||||||
|
public int GetReferenceBundleCount()
|
||||||
|
{
|
||||||
|
return _referenceBundleNames.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 447008dd110b8d746aafbe88c78bee5d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,225 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class BuildBundleInfo
|
||||||
|
{
|
||||||
|
#region 补丁文件的关键信息
|
||||||
|
/// <summary>
|
||||||
|
/// Unity引擎生成的哈希值(构建内容的哈希值)
|
||||||
|
/// </summary>
|
||||||
|
public string PackageUnityHash { set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unity引擎生成的CRC
|
||||||
|
/// </summary>
|
||||||
|
public uint PackageUnityCRC { set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文件哈希值
|
||||||
|
/// </summary>
|
||||||
|
public string PackageFileHash { set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文件哈希值
|
||||||
|
/// </summary>
|
||||||
|
public string PackageFileCRC { set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文件哈希值
|
||||||
|
/// </summary>
|
||||||
|
public long PackageFileSize { set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建输出的文件路径
|
||||||
|
/// </summary>
|
||||||
|
public string BuildOutputFilePath { set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 补丁包的源文件路径
|
||||||
|
/// </summary>
|
||||||
|
public string PackageSourceFilePath { set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 补丁包的目标文件路径
|
||||||
|
/// </summary>
|
||||||
|
public string PackageDestFilePath { set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加密生成文件的路径
|
||||||
|
/// 注意:如果未加密该路径为空
|
||||||
|
/// </summary>
|
||||||
|
public string EncryptedFilePath { set; get; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源包名称
|
||||||
|
/// </summary>
|
||||||
|
public string BundleName { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参与构建的资源列表
|
||||||
|
/// 注意:不包含零依赖资源和冗余资源
|
||||||
|
/// </summary>
|
||||||
|
public readonly List<BuildAssetInfo> AllMainAssets = new List<BuildAssetInfo>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Bundle文件的加载方法
|
||||||
|
/// </summary>
|
||||||
|
public EBundleLoadMethod LoadMethod { set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否为原生文件
|
||||||
|
/// </summary>
|
||||||
|
public bool IsRawFile
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
foreach (var assetInfo in AllMainAssets)
|
||||||
|
{
|
||||||
|
if (assetInfo.IsRawAsset)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否为加密文件
|
||||||
|
/// </summary>
|
||||||
|
public bool IsEncryptedFile
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(EncryptedFilePath))
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public BuildBundleInfo(string bundleName)
|
||||||
|
{
|
||||||
|
BundleName = bundleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加一个打包资源
|
||||||
|
/// </summary>
|
||||||
|
public void PackAsset(BuildAssetInfo assetInfo)
|
||||||
|
{
|
||||||
|
if (IsContainsAsset(assetInfo.AssetPath))
|
||||||
|
throw new System.Exception($"Asset is existed : {assetInfo.AssetPath}");
|
||||||
|
|
||||||
|
AllMainAssets.Add(assetInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否包含指定资源
|
||||||
|
/// </summary>
|
||||||
|
public bool IsContainsAsset(string assetPath)
|
||||||
|
{
|
||||||
|
foreach (var assetInfo in AllMainAssets)
|
||||||
|
{
|
||||||
|
if (assetInfo.AssetPath == assetPath)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取资源包的分类标签列表
|
||||||
|
/// </summary>
|
||||||
|
public string[] GetBundleTags()
|
||||||
|
{
|
||||||
|
List<string> result = new List<string>(AllMainAssets.Count);
|
||||||
|
foreach (var assetInfo in AllMainAssets)
|
||||||
|
{
|
||||||
|
foreach (var assetTag in assetInfo.BundleTags)
|
||||||
|
{
|
||||||
|
if (result.Contains(assetTag) == false)
|
||||||
|
result.Add(assetTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取构建的资源路径列表
|
||||||
|
/// </summary>
|
||||||
|
public string[] GetAllMainAssetPaths()
|
||||||
|
{
|
||||||
|
return AllMainAssets.Select(t => t.AssetPath).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取该资源包内的所有资源(包括零依赖资源和冗余资源)
|
||||||
|
/// </summary>
|
||||||
|
public List<string> GetAllBuiltinAssetPaths()
|
||||||
|
{
|
||||||
|
var packAssets = GetAllMainAssetPaths();
|
||||||
|
List<string> result = new List<string>(packAssets);
|
||||||
|
foreach (var assetInfo in AllMainAssets)
|
||||||
|
{
|
||||||
|
if (assetInfo.AllDependAssetInfos == null)
|
||||||
|
continue;
|
||||||
|
foreach (var dependAssetInfo in assetInfo.AllDependAssetInfos)
|
||||||
|
{
|
||||||
|
// 注意:依赖资源里只添加零依赖资源和冗余资源
|
||||||
|
if (dependAssetInfo.HasBundleName() == false)
|
||||||
|
{
|
||||||
|
if (result.Contains(dependAssetInfo.AssetPath) == false)
|
||||||
|
result.Add(dependAssetInfo.AssetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建AssetBundleBuild类
|
||||||
|
/// </summary>
|
||||||
|
public UnityEditor.AssetBundleBuild CreatePipelineBuild()
|
||||||
|
{
|
||||||
|
// 注意:我们不在支持AssetBundle的变种机制
|
||||||
|
AssetBundleBuild build = new AssetBundleBuild();
|
||||||
|
build.assetBundleName = BundleName;
|
||||||
|
build.assetBundleVariant = string.Empty;
|
||||||
|
build.assetNames = GetAllMainAssetPaths();
|
||||||
|
return build;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有写入补丁清单的资源
|
||||||
|
/// </summary>
|
||||||
|
public BuildAssetInfo[] GetAllManifestAssetInfos()
|
||||||
|
{
|
||||||
|
return AllMainAssets.Where(t => t.CollectorType == ECollectorType.MainAssetCollector).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建PackageBundle类
|
||||||
|
/// </summary>
|
||||||
|
internal PackageBundle CreatePackageBundle()
|
||||||
|
{
|
||||||
|
PackageBundle packageBundle = new PackageBundle();
|
||||||
|
packageBundle.BundleName = BundleName;
|
||||||
|
packageBundle.FileHash = PackageFileHash;
|
||||||
|
packageBundle.FileCRC = PackageFileCRC;
|
||||||
|
packageBundle.FileSize = PackageFileSize;
|
||||||
|
packageBundle.UnityCRC = PackageUnityCRC;
|
||||||
|
packageBundle.IsRawFile = IsRawFile;
|
||||||
|
packageBundle.LoadMethod = (byte)LoadMethod;
|
||||||
|
packageBundle.Tags = GetBundleTags();
|
||||||
|
return packageBundle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 826a9d7b4de0eba40b5c39b33747c011
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class BuildMapContext : IContextObject
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, BuildBundleInfo> _bundleInfoDic = new Dictionary<string, BuildBundleInfo>(10000);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 冗余的资源列表
|
||||||
|
/// </summary>
|
||||||
|
public readonly List<ReportRedundancyInfo> RedundancyInfos= new List<ReportRedundancyInfo>(1000);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 参与构建的资源总数
|
||||||
|
/// 说明:包括主动收集的资源以及其依赖的所有资源
|
||||||
|
/// </summary>
|
||||||
|
public int AssetFileCount;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 收集命令
|
||||||
|
/// </summary>
|
||||||
|
public CollectCommand Command { set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源包信息列表
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<string, BuildBundleInfo>.ValueCollection Collection
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _bundleInfoDic.Values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加一个打包资源
|
||||||
|
/// </summary>
|
||||||
|
public void PackAsset(BuildAssetInfo assetInfo)
|
||||||
|
{
|
||||||
|
string bundleName = assetInfo.BundleName;
|
||||||
|
if (string.IsNullOrEmpty(bundleName))
|
||||||
|
throw new Exception("Should never get here !");
|
||||||
|
|
||||||
|
if (_bundleInfoDic.TryGetValue(bundleName, out BuildBundleInfo bundleInfo))
|
||||||
|
{
|
||||||
|
bundleInfo.PackAsset(assetInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BuildBundleInfo newBundleInfo = new BuildBundleInfo(bundleName);
|
||||||
|
newBundleInfo.PackAsset(assetInfo);
|
||||||
|
_bundleInfoDic.Add(bundleName, newBundleInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否包含资源包
|
||||||
|
/// </summary>
|
||||||
|
public bool IsContainsBundle(string bundleName)
|
||||||
|
{
|
||||||
|
return _bundleInfoDic.ContainsKey(bundleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取资源包信息,如果没找到返回NULL
|
||||||
|
/// </summary>
|
||||||
|
public BuildBundleInfo GetBundleInfo(string bundleName)
|
||||||
|
{
|
||||||
|
if (_bundleInfoDic.TryGetValue(bundleName, out BuildBundleInfo result))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
throw new Exception($"Not found bundle : {bundleName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取构建管线里需要的数据
|
||||||
|
/// </summary>
|
||||||
|
public UnityEditor.AssetBundleBuild[] GetPipelineBuilds()
|
||||||
|
{
|
||||||
|
List<UnityEditor.AssetBundleBuild> builds = new List<UnityEditor.AssetBundleBuild>(_bundleInfoDic.Count);
|
||||||
|
foreach (var bundleInfo in _bundleInfoDic.Values)
|
||||||
|
{
|
||||||
|
if (bundleInfo.IsRawFile == false)
|
||||||
|
builds.Add(bundleInfo.CreatePipelineBuild());
|
||||||
|
}
|
||||||
|
return builds.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建着色器信息类
|
||||||
|
/// </summary>
|
||||||
|
public void CreateShadersBundleInfo(string shadersBundleName)
|
||||||
|
{
|
||||||
|
if (IsContainsBundle(shadersBundleName) == false)
|
||||||
|
{
|
||||||
|
var shaderBundleInfo = new BuildBundleInfo(shadersBundleName);
|
||||||
|
_bundleInfoDic.Add(shadersBundleName, shaderBundleInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8229aa3f8a369204db5c368715191e2f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 构建参数
|
||||||
|
/// </summary>
|
||||||
|
public class BuildParameters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// SBP构建参数
|
||||||
|
/// </summary>
|
||||||
|
public class SBPBuildParameters
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 生成代码防裁剪配置
|
||||||
|
/// </summary>
|
||||||
|
public bool WriteLinkXML = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缓存服务器地址
|
||||||
|
/// </summary>
|
||||||
|
public string CacheServerHost;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 缓存服务器端口
|
||||||
|
/// </summary>
|
||||||
|
public int CacheServerPort;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修复图集资源冗余问题
|
||||||
|
/// </summary>
|
||||||
|
public bool FixSpriteAtlasRedundancy = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 可编程构建管线的参数
|
||||||
|
/// </summary>
|
||||||
|
public SBPBuildParameters SBPParameters;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 内置资源的根目录
|
||||||
|
/// </summary>
|
||||||
|
public string StreamingAssetsRoot;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建输出的根目录
|
||||||
|
/// </summary>
|
||||||
|
public string BuildOutputRoot;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建的平台
|
||||||
|
/// </summary>
|
||||||
|
public BuildTarget BuildTarget;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建管线
|
||||||
|
/// </summary>
|
||||||
|
public EBuildPipeline BuildPipeline;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建模式
|
||||||
|
/// </summary>
|
||||||
|
public EBuildMode BuildMode;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建的包裹名称
|
||||||
|
/// </summary>
|
||||||
|
public string PackageName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建的包裹版本
|
||||||
|
/// </summary>
|
||||||
|
public string PackageVersion;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否显示普通日志
|
||||||
|
/// </summary>
|
||||||
|
public bool EnableLog = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证构建结果
|
||||||
|
/// </summary>
|
||||||
|
public bool VerifyBuildingResult = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 共享资源的打包规则
|
||||||
|
/// </summary>
|
||||||
|
public ISharedPackRule SharedPackRule = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源的加密接口
|
||||||
|
/// </summary>
|
||||||
|
public IEncryptionServices EncryptionServices = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 补丁文件名称的样式
|
||||||
|
/// </summary>
|
||||||
|
public EOutputNameStyle OutputNameStyle = EOutputNameStyle.HashName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 拷贝内置资源选项
|
||||||
|
/// </summary>
|
||||||
|
public ECopyBuildinFileOption CopyBuildinFileOption = ECopyBuildinFileOption.None;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 拷贝内置资源的标签
|
||||||
|
/// </summary>
|
||||||
|
public string CopyBuildinFileTags = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 压缩选项
|
||||||
|
/// </summary>
|
||||||
|
public ECompressOption CompressOption = ECompressOption.Uncompressed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 禁止写入类型树结构(可以降低包体和内存并提高加载效率)
|
||||||
|
/// </summary>
|
||||||
|
public bool DisableWriteTypeTree = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 忽略类型树变化
|
||||||
|
/// </summary>
|
||||||
|
public bool IgnoreTypeTreeChanges = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 98bb314dc26ba184fbb9e9fdcdb58a1d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class BuildParametersContext : IContextObject
|
||||||
|
{
|
||||||
|
private string _pipelineOutputDirectory = string.Empty;
|
||||||
|
private string _packageOutputDirectory = string.Empty;
|
||||||
|
private string _packageRootDirectory = string.Empty;
|
||||||
|
private string _streamingAssetsDirectory = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建参数
|
||||||
|
/// </summary>
|
||||||
|
public BuildParameters Parameters { private set; get; }
|
||||||
|
|
||||||
|
|
||||||
|
public BuildParametersContext(BuildParameters parameters)
|
||||||
|
{
|
||||||
|
Parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取构建管线的输出目录
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public string GetPipelineOutputDirectory()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(_pipelineOutputDirectory))
|
||||||
|
{
|
||||||
|
_pipelineOutputDirectory = $"{Parameters.BuildOutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}/{YooAssetSettings.OutputFolderName}";
|
||||||
|
}
|
||||||
|
return _pipelineOutputDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取本次构建的补丁输出目录
|
||||||
|
/// </summary>
|
||||||
|
public string GetPackageOutputDirectory()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(_packageOutputDirectory))
|
||||||
|
{
|
||||||
|
_packageOutputDirectory = $"{Parameters.BuildOutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}/{Parameters.PackageVersion}";
|
||||||
|
}
|
||||||
|
return _packageOutputDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取本次构建的补丁根目录
|
||||||
|
/// </summary>
|
||||||
|
public string GetPackageRootDirectory()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(_packageRootDirectory))
|
||||||
|
{
|
||||||
|
_packageRootDirectory = $"{Parameters.BuildOutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}";
|
||||||
|
}
|
||||||
|
return _packageRootDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取内置资源的目录
|
||||||
|
/// </summary>
|
||||||
|
public string GetStreamingAssetsDirectory()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(_streamingAssetsDirectory))
|
||||||
|
{
|
||||||
|
_streamingAssetsDirectory = $"{Parameters.StreamingAssetsRoot}/{Parameters.PackageName}";
|
||||||
|
}
|
||||||
|
return _streamingAssetsDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取内置构建管线的构建选项
|
||||||
|
/// </summary>
|
||||||
|
public BuildAssetBundleOptions GetPipelineBuildOptions()
|
||||||
|
{
|
||||||
|
// For the new build system, unity always need BuildAssetBundleOptions.CollectDependencies and BuildAssetBundleOptions.DeterministicAssetBundle
|
||||||
|
// 除非设置ForceRebuildAssetBundle标记,否则会进行增量打包
|
||||||
|
|
||||||
|
if (Parameters.BuildMode == EBuildMode.SimulateBuild)
|
||||||
|
throw new Exception("Should never get here !");
|
||||||
|
|
||||||
|
BuildAssetBundleOptions opt = BuildAssetBundleOptions.None;
|
||||||
|
opt |= BuildAssetBundleOptions.StrictMode; //Do not allow the build to succeed if any errors are reporting during it.
|
||||||
|
|
||||||
|
if (Parameters.BuildMode == EBuildMode.DryRunBuild)
|
||||||
|
{
|
||||||
|
opt |= BuildAssetBundleOptions.DryRunBuild;
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Parameters.CompressOption == ECompressOption.Uncompressed)
|
||||||
|
opt |= BuildAssetBundleOptions.UncompressedAssetBundle;
|
||||||
|
else if (Parameters.CompressOption == ECompressOption.LZ4)
|
||||||
|
opt |= BuildAssetBundleOptions.ChunkBasedCompression;
|
||||||
|
|
||||||
|
if (Parameters.BuildMode == EBuildMode.ForceRebuild)
|
||||||
|
opt |= BuildAssetBundleOptions.ForceRebuildAssetBundle; //Force rebuild the asset bundles
|
||||||
|
if (Parameters.DisableWriteTypeTree)
|
||||||
|
opt |= BuildAssetBundleOptions.DisableWriteTypeTree; //Do not include type information within the asset bundle (don't write type tree).
|
||||||
|
if (Parameters.IgnoreTypeTreeChanges)
|
||||||
|
opt |= BuildAssetBundleOptions.IgnoreTypeTreeChanges; //Ignore the type tree changes when doing the incremental build check.
|
||||||
|
|
||||||
|
opt |= BuildAssetBundleOptions.DisableLoadAssetByFileName; //Disables Asset Bundle LoadAsset by file name.
|
||||||
|
opt |= BuildAssetBundleOptions.DisableLoadAssetByFileNameWithExtension; //Disables Asset Bundle LoadAsset by file name with extension.
|
||||||
|
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取可编程构建管线的构建参数
|
||||||
|
/// </summary>
|
||||||
|
public UnityEditor.Build.Pipeline.BundleBuildParameters GetSBPBuildParameters()
|
||||||
|
{
|
||||||
|
if (Parameters.BuildMode == EBuildMode.SimulateBuild)
|
||||||
|
throw new Exception("Should never get here !");
|
||||||
|
|
||||||
|
var targetGroup = BuildPipeline.GetBuildTargetGroup(Parameters.BuildTarget);
|
||||||
|
var pipelineOutputDirectory = GetPipelineOutputDirectory();
|
||||||
|
var buildParams = new UnityEditor.Build.Pipeline.BundleBuildParameters(Parameters.BuildTarget, targetGroup, pipelineOutputDirectory);
|
||||||
|
|
||||||
|
if (Parameters.CompressOption == ECompressOption.Uncompressed)
|
||||||
|
buildParams.BundleCompression = UnityEngine.BuildCompression.Uncompressed;
|
||||||
|
else if (Parameters.CompressOption == ECompressOption.LZMA)
|
||||||
|
buildParams.BundleCompression = UnityEngine.BuildCompression.LZMA;
|
||||||
|
else if (Parameters.CompressOption == ECompressOption.LZ4)
|
||||||
|
buildParams.BundleCompression = UnityEngine.BuildCompression.LZ4;
|
||||||
|
else
|
||||||
|
throw new System.NotImplementedException(Parameters.CompressOption.ToString());
|
||||||
|
|
||||||
|
if (Parameters.DisableWriteTypeTree)
|
||||||
|
buildParams.ContentBuildFlags |= UnityEditor.Build.Content.ContentBuildFlags.DisableWriteTypeTree;
|
||||||
|
|
||||||
|
buildParams.UseCache = true;
|
||||||
|
buildParams.CacheServerHost = Parameters.SBPParameters.CacheServerHost;
|
||||||
|
buildParams.CacheServerPort = Parameters.SBPParameters.CacheServerPort;
|
||||||
|
buildParams.WriteLinkXML = Parameters.SBPParameters.WriteLinkXML;
|
||||||
|
|
||||||
|
return buildParams;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b84510feab7cbe44a9b6d8ef0b3f559c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2875232ad7f87c148b752d432f3a54f2
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class BuildContext
|
||||||
|
{
|
||||||
|
private readonly Dictionary<System.Type, IContextObject> _contextObjects = new Dictionary<System.Type, IContextObject>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空所有情景对象
|
||||||
|
/// </summary>
|
||||||
|
public void ClearAllContext()
|
||||||
|
{
|
||||||
|
_contextObjects.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置情景对象
|
||||||
|
/// </summary>
|
||||||
|
public void SetContextObject(IContextObject contextObject)
|
||||||
|
{
|
||||||
|
if (contextObject == null)
|
||||||
|
throw new ArgumentNullException("contextObject");
|
||||||
|
|
||||||
|
var type = contextObject.GetType();
|
||||||
|
if (_contextObjects.ContainsKey(type))
|
||||||
|
throw new Exception($"Context object {type} is already existed.");
|
||||||
|
|
||||||
|
_contextObjects.Add(type, contextObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取情景对象
|
||||||
|
/// </summary>
|
||||||
|
public T GetContextObject<T>() where T : IContextObject
|
||||||
|
{
|
||||||
|
var type = typeof(T);
|
||||||
|
if (_contextObjects.TryGetValue(type, out IContextObject contextObject))
|
||||||
|
{
|
||||||
|
return (T)contextObject;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"Not found context object : {type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6a232601f99c4634ea17fca4979f80ab
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public static class BuildLogger
|
||||||
|
{
|
||||||
|
private static bool _enableLog = true;
|
||||||
|
|
||||||
|
public static void InitLogger(bool enableLog)
|
||||||
|
{
|
||||||
|
_enableLog = enableLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Log(string message)
|
||||||
|
{
|
||||||
|
if (_enableLog)
|
||||||
|
{
|
||||||
|
Debug.Log(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void Warning(string message)
|
||||||
|
{
|
||||||
|
Debug.LogWarning(message);
|
||||||
|
}
|
||||||
|
public static void Error(string message)
|
||||||
|
{
|
||||||
|
Debug.LogError(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2bc82466a51f50141975e4424095aa09
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 构建结果
|
||||||
|
/// </summary>
|
||||||
|
public class BuildResult
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 构建是否成功
|
||||||
|
/// </summary>
|
||||||
|
public bool Success;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建失败的任务
|
||||||
|
/// </summary>
|
||||||
|
public string FailedTask;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建失败的信息
|
||||||
|
/// </summary>
|
||||||
|
public string ErrorInfo;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 输出的补丁包目录
|
||||||
|
/// </summary>
|
||||||
|
public string OutputPackageDirectory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e0855c4b5eaa26942bd7ad177fe3c288
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class BuildRunner
|
||||||
|
{
|
||||||
|
private static Stopwatch _buildWatch;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 总耗时
|
||||||
|
/// </summary>
|
||||||
|
public static int TotalSeconds = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行构建流程
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>如果成功返回TRUE,否则返回FALSE</returns>
|
||||||
|
public static BuildResult Run(List<IBuildTask> pipeline, BuildContext context)
|
||||||
|
{
|
||||||
|
if (pipeline == null)
|
||||||
|
throw new ArgumentNullException("pipeline");
|
||||||
|
if (context == null)
|
||||||
|
throw new ArgumentNullException("context");
|
||||||
|
|
||||||
|
BuildResult buildResult = new BuildResult();
|
||||||
|
buildResult.Success = true;
|
||||||
|
TotalSeconds = 0;
|
||||||
|
for (int i = 0; i < pipeline.Count; i++)
|
||||||
|
{
|
||||||
|
IBuildTask task = pipeline[i];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_buildWatch = Stopwatch.StartNew();
|
||||||
|
var taskAttribute = task.GetType().GetCustomAttribute<TaskAttribute>();
|
||||||
|
if (taskAttribute != null)
|
||||||
|
BuildLogger.Log($"---------------------------------------->{taskAttribute.TaskDesc}<---------------------------------------");
|
||||||
|
task.Run(context);
|
||||||
|
_buildWatch.Stop();
|
||||||
|
|
||||||
|
// 统计耗时
|
||||||
|
int seconds = GetBuildSeconds();
|
||||||
|
TotalSeconds += seconds;
|
||||||
|
if (taskAttribute != null)
|
||||||
|
BuildLogger.Log($"{taskAttribute.TaskDesc}耗时:{seconds}秒");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
EditorTools.ClearProgressBar();
|
||||||
|
buildResult.FailedTask = task.GetType().Name;
|
||||||
|
buildResult.ErrorInfo = e.ToString();
|
||||||
|
buildResult.Success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回运行结果
|
||||||
|
BuildLogger.Log($"构建过程总计耗时:{TotalSeconds}秒");
|
||||||
|
return buildResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int GetBuildSeconds()
|
||||||
|
{
|
||||||
|
float seconds = _buildWatch.ElapsedMilliseconds / 1000f;
|
||||||
|
return (int)seconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 79014124da678684388454d6ea892722
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public interface IBuildTask
|
||||||
|
{
|
||||||
|
void Run(BuildContext context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8888657c45e12c646a8349bac6bf0326
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public interface IContextObject
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 151a4acd5ad1c2046be20e080f9bdad4
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
|
public class TaskAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 任务说明
|
||||||
|
/// </summary>
|
||||||
|
public string TaskDesc;
|
||||||
|
|
||||||
|
public TaskAttribute(string taskDesc)
|
||||||
|
{
|
||||||
|
TaskDesc = taskDesc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 35749e57d9a3da84aa60c348bc6bbe9d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 254f430e0264bd84387878f8d7280e44
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor.Build.Content;
|
||||||
|
using UnityEngine.U2D;
|
||||||
|
using UnityEditor.Build.Pipeline.Injector;
|
||||||
|
using UnityEditor.Build.Pipeline.Interfaces;
|
||||||
|
using UnityEngine;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace UnityEditor.Build.Pipeline.Tasks
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Ref https://zhuanlan.zhihu.com/p/586918159
|
||||||
|
/// </summary>
|
||||||
|
public class RemoveSpriteAtlasRedundancy : IBuildTask
|
||||||
|
{
|
||||||
|
public int Version => 1;
|
||||||
|
|
||||||
|
[InjectContext]
|
||||||
|
IBundleWriteData writeDataParam;
|
||||||
|
|
||||||
|
public ReturnCode Run()
|
||||||
|
{
|
||||||
|
#if UNITY_2020_3_OR_NEWER
|
||||||
|
BundleWriteData writeData = (BundleWriteData)writeDataParam;
|
||||||
|
|
||||||
|
// 图集引用的精灵图片集合
|
||||||
|
HashSet<GUID> spriteGuids = new HashSet<GUID>();
|
||||||
|
foreach (var pair in writeData.FileToObjects)
|
||||||
|
{
|
||||||
|
foreach (ObjectIdentifier objectIdentifier in pair.Value)
|
||||||
|
{
|
||||||
|
var assetPath = AssetDatabase.GUIDToAssetPath(objectIdentifier.guid);
|
||||||
|
var assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
|
||||||
|
if (assetType == typeof(SpriteAtlas))
|
||||||
|
{
|
||||||
|
var spritePaths = AssetDatabase.GetDependencies(assetPath, false);
|
||||||
|
foreach (string spritePath in spritePaths)
|
||||||
|
{
|
||||||
|
GUID spriteGuild = AssetDatabase.GUIDFromAssetPath(spritePath);
|
||||||
|
spriteGuids.Add(spriteGuild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除图集引用的精力图片对象
|
||||||
|
foreach (var pair in writeData.FileToObjects)
|
||||||
|
{
|
||||||
|
List<ObjectIdentifier> objectIdentifiers = pair.Value;
|
||||||
|
for (int i = objectIdentifiers.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
ObjectIdentifier objectIdentifier = objectIdentifiers[i];
|
||||||
|
if (spriteGuids.Contains(objectIdentifier.guid))
|
||||||
|
{
|
||||||
|
if (objectIdentifier.localIdentifierInFile == 2800000)
|
||||||
|
{
|
||||||
|
// 删除图集散图的冗余纹理
|
||||||
|
objectIdentifiers.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ReturnCode.Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f01d5c82be95c8f4b93aeefc0454ae5c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor.Build.Pipeline;
|
||||||
|
using UnityEditor.Build.Pipeline.Interfaces;
|
||||||
|
|
||||||
|
namespace UnityEditor.Build.Pipeline.Tasks
|
||||||
|
{
|
||||||
|
public static class SBPBuildTasks
|
||||||
|
{
|
||||||
|
public static IList<IBuildTask> Create(bool fixSpriteAtlasRedundancy, string builtInShaderBundleName)
|
||||||
|
{
|
||||||
|
var buildTasks = new List<IBuildTask>();
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
buildTasks.Add(new SwitchToBuildPlatform());
|
||||||
|
buildTasks.Add(new RebuildSpriteAtlasCache());
|
||||||
|
|
||||||
|
// Player Scripts
|
||||||
|
buildTasks.Add(new BuildPlayerScripts());
|
||||||
|
buildTasks.Add(new PostScriptsCallback());
|
||||||
|
|
||||||
|
// Dependency
|
||||||
|
buildTasks.Add(new CalculateSceneDependencyData());
|
||||||
|
#if UNITY_2019_3_OR_NEWER
|
||||||
|
buildTasks.Add(new CalculateCustomDependencyData());
|
||||||
|
#endif
|
||||||
|
buildTasks.Add(new CalculateAssetDependencyData());
|
||||||
|
buildTasks.Add(new StripUnusedSpriteSources());
|
||||||
|
buildTasks.Add(new CreateBuiltInShadersBundle(builtInShaderBundleName));
|
||||||
|
buildTasks.Add(new PostDependencyCallback());
|
||||||
|
|
||||||
|
// Packing
|
||||||
|
buildTasks.Add(new GenerateBundlePacking());
|
||||||
|
if (fixSpriteAtlasRedundancy)
|
||||||
|
buildTasks.Add(new RemoveSpriteAtlasRedundancy());
|
||||||
|
buildTasks.Add(new UpdateBundleObjectLayout());
|
||||||
|
buildTasks.Add(new GenerateBundleCommands());
|
||||||
|
buildTasks.Add(new GenerateSubAssetPathMaps());
|
||||||
|
buildTasks.Add(new GenerateBundleMaps());
|
||||||
|
buildTasks.Add(new PostPackingCallback());
|
||||||
|
|
||||||
|
// Writing
|
||||||
|
buildTasks.Add(new WriteSerializedFiles());
|
||||||
|
buildTasks.Add(new ArchiveAndCompressBundles());
|
||||||
|
buildTasks.Add(new AppendBundleHash());
|
||||||
|
buildTasks.Add(new GenerateLinkXml());
|
||||||
|
buildTasks.Add(new PostWritingCallback());
|
||||||
|
|
||||||
|
return buildTasks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f38422f6a64300243af6b4fbf84644ba
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[TaskAttribute("资源构建内容打包")]
|
||||||
|
public class TaskBuilding : IBuildTask
|
||||||
|
{
|
||||||
|
public class BuildResultContext : IContextObject
|
||||||
|
{
|
||||||
|
public AssetBundleManifest UnityManifest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IBuildTask.Run(BuildContext context)
|
||||||
|
{
|
||||||
|
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||||
|
|
||||||
|
// 模拟构建模式下跳过引擎构建
|
||||||
|
var buildMode = buildParametersContext.Parameters.BuildMode;
|
||||||
|
if (buildMode == EBuildMode.SimulateBuild)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 开始构建
|
||||||
|
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
|
||||||
|
BuildAssetBundleOptions buildOptions = buildParametersContext.GetPipelineBuildOptions();
|
||||||
|
AssetBundleManifest buildResults = BuildPipeline.BuildAssetBundles(pipelineOutputDirectory, buildMapContext.GetPipelineBuilds(), buildOptions, buildParametersContext.Parameters.BuildTarget);
|
||||||
|
if (buildResults == null)
|
||||||
|
{
|
||||||
|
throw new Exception("构建过程中发生错误!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
|
||||||
|
{
|
||||||
|
string unityOutputManifestFilePath = $"{pipelineOutputDirectory}/{YooAssetSettings.OutputFolderName}";
|
||||||
|
if (System.IO.File.Exists(unityOutputManifestFilePath) == false)
|
||||||
|
throw new Exception("构建过程中发生严重错误!请查阅上下文日志!");
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildLogger.Log("Unity引擎打包成功!");
|
||||||
|
BuildResultContext buildResultContext = new BuildResultContext();
|
||||||
|
buildResultContext.UnityManifest = buildResults;
|
||||||
|
context.SetContextObject(buildResultContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9466e826c135e994c84961e4b921ca5f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using UnityEditor.Build.Pipeline;
|
||||||
|
using UnityEditor.Build.Pipeline.Interfaces;
|
||||||
|
using UnityEditor.Build.Pipeline.Tasks;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[TaskAttribute("资源构建内容打包")]
|
||||||
|
public class TaskBuilding_SBP : IBuildTask
|
||||||
|
{
|
||||||
|
public class BuildResultContext : IContextObject
|
||||||
|
{
|
||||||
|
public IBundleBuildResults Results;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IBuildTask.Run(BuildContext context)
|
||||||
|
{
|
||||||
|
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||||
|
|
||||||
|
// 模拟构建模式下跳过引擎构建
|
||||||
|
var buildMode = buildParametersContext.Parameters.BuildMode;
|
||||||
|
if (buildMode == EBuildMode.SimulateBuild)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 构建内容
|
||||||
|
var buildContent = new BundleBuildContent(buildMapContext.GetPipelineBuilds());
|
||||||
|
|
||||||
|
// 开始构建
|
||||||
|
IBundleBuildResults buildResults;
|
||||||
|
var buildParameters = buildParametersContext.GetSBPBuildParameters();
|
||||||
|
var taskList = SBPBuildTasks.Create(buildParametersContext.Parameters.SBPParameters.FixSpriteAtlasRedundancy, buildMapContext.Command.ShadersBundleName);
|
||||||
|
ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParameters, buildContent, out buildResults, taskList);
|
||||||
|
if (exitCode < 0)
|
||||||
|
{
|
||||||
|
throw new Exception($"构建过程中发生错误 : {exitCode}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建着色器信息
|
||||||
|
// 说明:解决因为着色器资源包导致验证失败。
|
||||||
|
// 例如:当项目里没有着色器,如果有依赖内置着色器就会验证失败。
|
||||||
|
string shadersBundleName = buildMapContext.Command.ShadersBundleName;
|
||||||
|
if (buildResults.BundleInfos.ContainsKey(shadersBundleName))
|
||||||
|
{
|
||||||
|
buildMapContext.CreateShadersBundleInfo(shadersBundleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildLogger.Log("Unity引擎打包成功!");
|
||||||
|
BuildResultContext buildResultContext = new BuildResultContext();
|
||||||
|
buildResultContext.Results = buildResults;
|
||||||
|
context.SetContextObject(buildResultContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1af5fed7e9f83174d868c12b41c4a79e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[TaskAttribute("拷贝内置文件到流目录")]
|
||||||
|
public class TaskCopyBuildinFiles : IBuildTask
|
||||||
|
{
|
||||||
|
void IBuildTask.Run(BuildContext context)
|
||||||
|
{
|
||||||
|
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var manifestContext = context.GetContextObject<ManifestContext>();
|
||||||
|
var buildMode = buildParametersContext.Parameters.BuildMode;
|
||||||
|
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
|
||||||
|
{
|
||||||
|
if (buildParametersContext.Parameters.CopyBuildinFileOption != ECopyBuildinFileOption.None)
|
||||||
|
{
|
||||||
|
CopyBuildinFilesToStreaming(buildParametersContext, manifestContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 拷贝首包资源文件
|
||||||
|
/// </summary>
|
||||||
|
private void CopyBuildinFilesToStreaming(BuildParametersContext buildParametersContext, ManifestContext manifestContext)
|
||||||
|
{
|
||||||
|
ECopyBuildinFileOption option = buildParametersContext.Parameters.CopyBuildinFileOption;
|
||||||
|
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
|
||||||
|
string streamingAssetsDirectory = buildParametersContext.GetStreamingAssetsDirectory();
|
||||||
|
string buildPackageName = buildParametersContext.Parameters.PackageName;
|
||||||
|
string buildPackageVersion = buildParametersContext.Parameters.PackageVersion;
|
||||||
|
|
||||||
|
// 加载补丁清单
|
||||||
|
PackageManifest manifest = manifestContext.Manifest;
|
||||||
|
|
||||||
|
// 清空流目录
|
||||||
|
if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.ClearAndCopyByTags)
|
||||||
|
{
|
||||||
|
EditorTools.ClearFolder(streamingAssetsDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拷贝补丁清单文件
|
||||||
|
{
|
||||||
|
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildPackageName, buildPackageVersion);
|
||||||
|
string sourcePath = $"{packageOutputDirectory}/{fileName}";
|
||||||
|
string destPath = $"{streamingAssetsDirectory}/{fileName}";
|
||||||
|
EditorTools.CopyFile(sourcePath, destPath, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拷贝补丁清单哈希文件
|
||||||
|
{
|
||||||
|
string fileName = YooAssetSettingsData.GetPackageHashFileName(buildPackageName, buildPackageVersion);
|
||||||
|
string sourcePath = $"{packageOutputDirectory}/{fileName}";
|
||||||
|
string destPath = $"{streamingAssetsDirectory}/{fileName}";
|
||||||
|
EditorTools.CopyFile(sourcePath, destPath, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拷贝补丁清单版本文件
|
||||||
|
{
|
||||||
|
string fileName = YooAssetSettingsData.GetPackageVersionFileName(buildPackageName);
|
||||||
|
string sourcePath = $"{packageOutputDirectory}/{fileName}";
|
||||||
|
string destPath = $"{streamingAssetsDirectory}/{fileName}";
|
||||||
|
EditorTools.CopyFile(sourcePath, destPath, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拷贝文件列表(所有文件)
|
||||||
|
if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.OnlyCopyAll)
|
||||||
|
{
|
||||||
|
foreach (var packageBundle in manifest.BundleList)
|
||||||
|
{
|
||||||
|
string sourcePath = $"{packageOutputDirectory}/{packageBundle.FileName}";
|
||||||
|
string destPath = $"{streamingAssetsDirectory}/{packageBundle.FileName}";
|
||||||
|
EditorTools.CopyFile(sourcePath, destPath, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拷贝文件列表(带标签的文件)
|
||||||
|
if (option == ECopyBuildinFileOption.ClearAndCopyByTags || option == ECopyBuildinFileOption.OnlyCopyByTags)
|
||||||
|
{
|
||||||
|
string[] tags = buildParametersContext.Parameters.CopyBuildinFileTags.Split(';');
|
||||||
|
foreach (var packageBundle in manifest.BundleList)
|
||||||
|
{
|
||||||
|
if (packageBundle.HasTag(tags) == false)
|
||||||
|
continue;
|
||||||
|
string sourcePath = $"{packageOutputDirectory}/{packageBundle.FileName}";
|
||||||
|
string destPath = $"{streamingAssetsDirectory}/{packageBundle.FileName}";
|
||||||
|
EditorTools.CopyFile(sourcePath, destPath, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新目录
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
BuildLogger.Log($"内置文件拷贝完成:{streamingAssetsDirectory}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5c77e17c3a3a57548a218f1cd26f5a55
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[TaskAttribute("拷贝原生文件")]
|
||||||
|
public class TaskCopyRawFile : IBuildTask
|
||||||
|
{
|
||||||
|
void IBuildTask.Run(BuildContext context)
|
||||||
|
{
|
||||||
|
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var buildParameters = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||||
|
|
||||||
|
var buildMode = buildParameters.Parameters.BuildMode;
|
||||||
|
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
|
||||||
|
{
|
||||||
|
CopyRawBundle(buildMapContext, buildParametersContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 拷贝原生文件
|
||||||
|
/// </summary>
|
||||||
|
private void CopyRawBundle(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext)
|
||||||
|
{
|
||||||
|
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
|
||||||
|
foreach (var bundleInfo in buildMapContext.Collection)
|
||||||
|
{
|
||||||
|
if (bundleInfo.IsRawFile)
|
||||||
|
{
|
||||||
|
string dest = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
|
||||||
|
foreach (var assetInfo in bundleInfo.AllMainAssets)
|
||||||
|
{
|
||||||
|
if (assetInfo.IsRawAsset)
|
||||||
|
EditorTools.CopyFile(assetInfo.AssetPath, dest, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3625d4b8b5b79324ebf7ec19a87677e7
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,384 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using UnityEditor.Build.Pipeline;
|
||||||
|
using UnityEditor.Build.Pipeline.Interfaces;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
public class ManifestContext : IContextObject
|
||||||
|
{
|
||||||
|
internal PackageManifest Manifest;
|
||||||
|
}
|
||||||
|
|
||||||
|
[TaskAttribute("创建清单文件")]
|
||||||
|
public class TaskCreateManifest : IBuildTask
|
||||||
|
{
|
||||||
|
void IBuildTask.Run(BuildContext context)
|
||||||
|
{
|
||||||
|
CreateManifestFile(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建补丁清单文件到输出目录
|
||||||
|
/// </summary>
|
||||||
|
private void CreateManifestFile(BuildContext context)
|
||||||
|
{
|
||||||
|
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||||
|
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var buildParameters = buildParametersContext.Parameters;
|
||||||
|
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
|
||||||
|
|
||||||
|
// 创建新补丁清单
|
||||||
|
PackageManifest manifest = new PackageManifest();
|
||||||
|
manifest.FileVersion = YooAssetSettings.ManifestFileVersion;
|
||||||
|
manifest.EnableAddressable = buildMapContext.Command.EnableAddressable;
|
||||||
|
manifest.LocationToLower = buildMapContext.Command.LocationToLower;
|
||||||
|
manifest.IncludeAssetGUID = buildMapContext.Command.IncludeAssetGUID;
|
||||||
|
manifest.OutputNameStyle = (int)buildParameters.OutputNameStyle;
|
||||||
|
manifest.PackageName = buildParameters.PackageName;
|
||||||
|
manifest.PackageVersion = buildParameters.PackageVersion;
|
||||||
|
|
||||||
|
// 填充资源包集合
|
||||||
|
manifest.BundleList = GetAllPackageBundle(context);
|
||||||
|
CacheBundleIDs(manifest);
|
||||||
|
|
||||||
|
// 填充主资源集合
|
||||||
|
manifest.AssetList = GetAllPackageAsset(context, manifest);
|
||||||
|
|
||||||
|
// 更新Unity内置资源包的引用关系
|
||||||
|
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
|
||||||
|
{
|
||||||
|
if (buildParameters.BuildMode == EBuildMode.IncrementalBuild)
|
||||||
|
{
|
||||||
|
var buildResultContext = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
|
||||||
|
UpdateBuiltInBundleReference(manifest, buildResultContext, buildMapContext.Command.ShadersBundleName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新资源包之间的引用关系
|
||||||
|
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
|
||||||
|
{
|
||||||
|
if (buildParameters.BuildMode == EBuildMode.IncrementalBuild)
|
||||||
|
{
|
||||||
|
var buildResultContext = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
|
||||||
|
UpdateScriptPipelineReference(manifest, buildResultContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新资源包之间的引用关系
|
||||||
|
if (buildParameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
|
||||||
|
{
|
||||||
|
if (buildParameters.BuildMode != EBuildMode.SimulateBuild)
|
||||||
|
{
|
||||||
|
var buildResultContext = context.GetContextObject<TaskBuilding.BuildResultContext>();
|
||||||
|
UpdateBuiltinPipelineReference(manifest, buildResultContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建补丁清单文本文件
|
||||||
|
{
|
||||||
|
string fileName = YooAssetSettingsData.GetManifestJsonFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||||
|
string filePath = $"{packageOutputDirectory}/{fileName}";
|
||||||
|
ManifestTools.SerializeToJson(filePath, manifest);
|
||||||
|
BuildLogger.Log($"创建补丁清单文件:{filePath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建补丁清单二进制文件
|
||||||
|
string packageHash;
|
||||||
|
{
|
||||||
|
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||||
|
string filePath = $"{packageOutputDirectory}/{fileName}";
|
||||||
|
ManifestTools.SerializeToBinary(filePath, manifest);
|
||||||
|
packageHash = HashUtility.FileMD5(filePath);
|
||||||
|
BuildLogger.Log($"创建补丁清单文件:{filePath}");
|
||||||
|
|
||||||
|
ManifestContext manifestContext = new ManifestContext();
|
||||||
|
byte[] bytesData = FileUtility.ReadAllBytes(filePath);
|
||||||
|
manifestContext.Manifest = ManifestTools.DeserializeFromBinary(bytesData);
|
||||||
|
context.SetContextObject(manifestContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建补丁清单哈希文件
|
||||||
|
{
|
||||||
|
string fileName = YooAssetSettingsData.GetPackageHashFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||||
|
string filePath = $"{packageOutputDirectory}/{fileName}";
|
||||||
|
FileUtility.WriteAllText(filePath, packageHash);
|
||||||
|
BuildLogger.Log($"创建补丁清单哈希文件:{filePath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建补丁清单版本文件
|
||||||
|
{
|
||||||
|
string fileName = YooAssetSettingsData.GetPackageVersionFileName(buildParameters.PackageName);
|
||||||
|
string filePath = $"{packageOutputDirectory}/{fileName}";
|
||||||
|
FileUtility.WriteAllText(filePath, buildParameters.PackageVersion);
|
||||||
|
BuildLogger.Log($"创建补丁清单版本文件:{filePath}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取资源包列表
|
||||||
|
/// </summary>
|
||||||
|
private List<PackageBundle> GetAllPackageBundle(BuildContext context)
|
||||||
|
{
|
||||||
|
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||||
|
|
||||||
|
List<PackageBundle> result = new List<PackageBundle>(1000);
|
||||||
|
foreach (var bundleInfo in buildMapContext.Collection)
|
||||||
|
{
|
||||||
|
var packageBundle = bundleInfo.CreatePackageBundle();
|
||||||
|
result.Add(packageBundle);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取资源列表
|
||||||
|
/// </summary>
|
||||||
|
private List<PackageAsset> GetAllPackageAsset(BuildContext context, PackageManifest manifest)
|
||||||
|
{
|
||||||
|
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||||
|
|
||||||
|
List<PackageAsset> result = new List<PackageAsset>(1000);
|
||||||
|
foreach (var bundleInfo in buildMapContext.Collection)
|
||||||
|
{
|
||||||
|
var assetInfos = bundleInfo.GetAllManifestAssetInfos();
|
||||||
|
foreach (var assetInfo in assetInfos)
|
||||||
|
{
|
||||||
|
PackageAsset packageAsset = new PackageAsset();
|
||||||
|
packageAsset.Address = buildMapContext.Command.EnableAddressable ? assetInfo.Address : string.Empty;
|
||||||
|
packageAsset.AssetPath = assetInfo.AssetPath;
|
||||||
|
packageAsset.AssetGUID = buildMapContext.Command.IncludeAssetGUID ? assetInfo.AssetGUID : string.Empty;
|
||||||
|
packageAsset.AssetTags = assetInfo.AssetTags.ToArray();
|
||||||
|
packageAsset.BundleID = GetCachedBundleID(assetInfo.BundleName);
|
||||||
|
packageAsset.DependIDs = GetAssetBundleDependIDs(packageAsset.BundleID, assetInfo, manifest);
|
||||||
|
result.Add(packageAsset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
private int[] GetAssetBundleDependIDs(int mainBundleID, BuildAssetInfo assetInfo, PackageManifest manifest)
|
||||||
|
{
|
||||||
|
HashSet<int> result = new HashSet<int>();
|
||||||
|
foreach (var dependAssetInfo in assetInfo.AllDependAssetInfos)
|
||||||
|
{
|
||||||
|
if (dependAssetInfo.HasBundleName())
|
||||||
|
{
|
||||||
|
int bundleID = GetCachedBundleID(dependAssetInfo.BundleName);
|
||||||
|
if (mainBundleID != bundleID)
|
||||||
|
{
|
||||||
|
if (result.Contains(bundleID) == false)
|
||||||
|
result.Add(bundleID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新Unity内置资源包的引用关系
|
||||||
|
/// </summary>
|
||||||
|
private void UpdateBuiltInBundleReference(PackageManifest manifest, TaskBuilding_SBP.BuildResultContext buildResultContext, string shadersBunldeName)
|
||||||
|
{
|
||||||
|
// 获取所有依赖着色器资源包的资源包列表
|
||||||
|
List<string> shaderBundleReferenceList = new List<string>();
|
||||||
|
foreach (var valuePair in buildResultContext.Results.BundleInfos)
|
||||||
|
{
|
||||||
|
if (valuePair.Value.Dependencies.Any(t => t == shadersBunldeName))
|
||||||
|
shaderBundleReferenceList.Add(valuePair.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注意:没有任何资源依赖着色器
|
||||||
|
if (shaderBundleReferenceList.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 获取着色器资源包索引
|
||||||
|
Predicate<PackageBundle> predicate = new Predicate<PackageBundle>(s => s.BundleName == shadersBunldeName);
|
||||||
|
int shaderBundleId = manifest.BundleList.FindIndex(predicate);
|
||||||
|
if (shaderBundleId == -1)
|
||||||
|
throw new Exception("没有发现着色器资源包!");
|
||||||
|
|
||||||
|
// 检测依赖交集并更新依赖ID
|
||||||
|
HashSet<string> tagTemps = new HashSet<string>();
|
||||||
|
foreach (var packageAsset in manifest.AssetList)
|
||||||
|
{
|
||||||
|
List<string> dependBundles = GetPackageAssetAllDependBundles(manifest, packageAsset);
|
||||||
|
List<string> conflictAssetPathList = dependBundles.Intersect(shaderBundleReferenceList).ToList();
|
||||||
|
if (conflictAssetPathList.Count > 0)
|
||||||
|
{
|
||||||
|
HashSet<int> newDependIDs = new HashSet<int>(packageAsset.DependIDs);
|
||||||
|
if (newDependIDs.Contains(shaderBundleId) == false)
|
||||||
|
newDependIDs.Add(shaderBundleId);
|
||||||
|
packageAsset.DependIDs = newDependIDs.ToArray();
|
||||||
|
foreach (var tag in packageAsset.AssetTags)
|
||||||
|
{
|
||||||
|
if (tagTemps.Contains(tag) == false)
|
||||||
|
tagTemps.Add(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新资源包标签
|
||||||
|
var packageBundle = manifest.BundleList[shaderBundleId];
|
||||||
|
HashSet<string> newTags = new HashSet<string>(packageBundle.Tags);
|
||||||
|
foreach (var tag in tagTemps)
|
||||||
|
{
|
||||||
|
if (newTags.Contains(tag) == false)
|
||||||
|
newTags.Add(tag);
|
||||||
|
}
|
||||||
|
packageBundle.Tags = newTags.ToArray();
|
||||||
|
}
|
||||||
|
private List<string> GetPackageAssetAllDependBundles(PackageManifest manifest, PackageAsset packageAsset)
|
||||||
|
{
|
||||||
|
List<string> result = new List<string>();
|
||||||
|
string mainBundle = manifest.BundleList[packageAsset.BundleID].BundleName;
|
||||||
|
result.Add(mainBundle);
|
||||||
|
foreach (var dependID in packageAsset.DependIDs)
|
||||||
|
{
|
||||||
|
string dependBundle = manifest.BundleList[dependID].BundleName;
|
||||||
|
result.Add(dependBundle);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 资源包引用关系相关
|
||||||
|
private readonly Dictionary<string, int> _cachedBundleID = new Dictionary<string, int>(10000);
|
||||||
|
private readonly Dictionary<string, string[]> _cachedBundleDepends = new Dictionary<string, string[]>(10000);
|
||||||
|
|
||||||
|
private void CacheBundleIDs(PackageManifest manifest)
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.Assert(manifest.BundleList.Count != 0, "Manifest bundle list is empty !");
|
||||||
|
for (int index = 0; index < manifest.BundleList.Count; index++)
|
||||||
|
{
|
||||||
|
string bundleName = manifest.BundleList[index].BundleName;
|
||||||
|
_cachedBundleID.Add(bundleName, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateScriptPipelineReference(PackageManifest manifest, TaskBuilding_SBP.BuildResultContext buildResultContext)
|
||||||
|
{
|
||||||
|
int progressValue;
|
||||||
|
int totalCount = manifest.BundleList.Count;
|
||||||
|
|
||||||
|
// 缓存资源包依赖
|
||||||
|
_cachedBundleDepends.Clear();
|
||||||
|
progressValue = 0;
|
||||||
|
foreach (var packageBundle in manifest.BundleList)
|
||||||
|
{
|
||||||
|
if (packageBundle.IsRawFile)
|
||||||
|
{
|
||||||
|
_cachedBundleDepends.Add(packageBundle.BundleName, new string[] { });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buildResultContext.Results.BundleInfos.ContainsKey(packageBundle.BundleName) == false)
|
||||||
|
throw new Exception($"Not found bundle in SBP build results : {packageBundle.BundleName}");
|
||||||
|
|
||||||
|
var depends = buildResultContext.Results.BundleInfos[packageBundle.BundleName].Dependencies;
|
||||||
|
_cachedBundleDepends.Add(packageBundle.BundleName, depends);
|
||||||
|
int pro = ++progressValue;
|
||||||
|
if (pro % 100 == 0)
|
||||||
|
{
|
||||||
|
EditorTools.DisplayProgressBar("缓存资源包依赖列表", pro, totalCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorTools.ClearProgressBar();
|
||||||
|
|
||||||
|
// 计算资源包引用列表
|
||||||
|
foreach (var packageBundle in manifest.BundleList)
|
||||||
|
{
|
||||||
|
packageBundle.ReferenceIDs = GetBundleRefrenceIDs(manifest, packageBundle);
|
||||||
|
int pro = ++progressValue;
|
||||||
|
if (pro % 100 == 0)
|
||||||
|
{
|
||||||
|
EditorTools.DisplayProgressBar("计算资源包引用关系", pro, totalCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorTools.ClearProgressBar();
|
||||||
|
}
|
||||||
|
private void UpdateBuiltinPipelineReference(PackageManifest manifest, TaskBuilding.BuildResultContext buildResultContext)
|
||||||
|
{
|
||||||
|
int progressValue;
|
||||||
|
int totalCount = manifest.BundleList.Count;
|
||||||
|
|
||||||
|
// 缓存资源包依赖
|
||||||
|
_cachedBundleDepends.Clear();
|
||||||
|
progressValue = 0;
|
||||||
|
foreach (var packageBundle in manifest.BundleList)
|
||||||
|
{
|
||||||
|
if (packageBundle.IsRawFile)
|
||||||
|
{
|
||||||
|
_cachedBundleDepends.Add(packageBundle.BundleName, new string[] { });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var depends = buildResultContext.UnityManifest.GetDirectDependencies(packageBundle.BundleName);
|
||||||
|
_cachedBundleDepends.Add(packageBundle.BundleName, depends);
|
||||||
|
int pro = ++progressValue;
|
||||||
|
if (pro % 100 == 0)
|
||||||
|
{
|
||||||
|
EditorTools.DisplayProgressBar("缓存资源包依赖列表", pro, totalCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorTools.ClearProgressBar();
|
||||||
|
|
||||||
|
// 计算资源包引用列表
|
||||||
|
progressValue = 0;
|
||||||
|
foreach (var packageBundle in manifest.BundleList)
|
||||||
|
{
|
||||||
|
packageBundle.ReferenceIDs = GetBundleRefrenceIDs(manifest, packageBundle);
|
||||||
|
int pro = ++progressValue;
|
||||||
|
if (pro % 100 == 0)
|
||||||
|
{
|
||||||
|
EditorTools.DisplayProgressBar("计算资源包引用关系", ++progressValue, totalCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorTools.ClearProgressBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] GetBundleRefrenceIDs(PackageManifest manifest, PackageBundle targetBundle)
|
||||||
|
{
|
||||||
|
List<string> referenceList = new List<string>();
|
||||||
|
foreach (var packageBundle in manifest.BundleList)
|
||||||
|
{
|
||||||
|
string bundleName = packageBundle.BundleName;
|
||||||
|
if (bundleName == targetBundle.BundleName)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string[] dependencies = GetCachedBundleDepends(bundleName);
|
||||||
|
if (dependencies.Contains(targetBundle.BundleName))
|
||||||
|
{
|
||||||
|
referenceList.Add(bundleName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HashSet<int> result = new HashSet<int>();
|
||||||
|
foreach (var bundleName in referenceList)
|
||||||
|
{
|
||||||
|
int bundleID = GetCachedBundleID(bundleName);
|
||||||
|
if (result.Contains(bundleID) == false)
|
||||||
|
result.Add(bundleID);
|
||||||
|
}
|
||||||
|
return result.ToArray();
|
||||||
|
}
|
||||||
|
private int GetCachedBundleID(string bundleName)
|
||||||
|
{
|
||||||
|
if (_cachedBundleID.TryGetValue(bundleName, out int value) == false)
|
||||||
|
{
|
||||||
|
throw new Exception($"Not found cached bundle ID : {bundleName}");
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
private string[] GetCachedBundleDepends(string bundleName)
|
||||||
|
{
|
||||||
|
if (_cachedBundleDepends.TryGetValue(bundleName, out string[] value) == false)
|
||||||
|
{
|
||||||
|
throw new Exception($"Not found cached bundle depends : {bundleName}");
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 566c37f5a59f2e84397a9527981a7310
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[TaskAttribute("制作包裹")]
|
||||||
|
public class TaskCreatePackage : IBuildTask
|
||||||
|
{
|
||||||
|
void IBuildTask.Run(BuildContext context)
|
||||||
|
{
|
||||||
|
var buildParameters = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||||
|
var buildMode = buildParameters.Parameters.BuildMode;
|
||||||
|
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
|
||||||
|
{
|
||||||
|
CopyPackageFiles(buildParameters, buildMapContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 拷贝补丁文件到补丁包目录
|
||||||
|
/// </summary>
|
||||||
|
private void CopyPackageFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext)
|
||||||
|
{
|
||||||
|
var buildParameters = buildParametersContext.Parameters;
|
||||||
|
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
|
||||||
|
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
|
||||||
|
BuildLogger.Log($"开始拷贝补丁文件到补丁包目录:{packageOutputDirectory}");
|
||||||
|
|
||||||
|
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
|
||||||
|
{
|
||||||
|
// 拷贝构建日志
|
||||||
|
{
|
||||||
|
string sourcePath = $"{pipelineOutputDirectory}/buildlogtep.json";
|
||||||
|
string destPath = $"{packageOutputDirectory}/buildlogtep.json";
|
||||||
|
EditorTools.CopyFile(sourcePath, destPath, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拷贝代码防裁剪配置
|
||||||
|
if (buildParameters.SBPParameters.WriteLinkXML)
|
||||||
|
{
|
||||||
|
string sourcePath = $"{pipelineOutputDirectory}/link.xml";
|
||||||
|
string destPath = $"{packageOutputDirectory}/link.xml";
|
||||||
|
EditorTools.CopyFile(sourcePath, destPath, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (buildParameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
|
||||||
|
{
|
||||||
|
// 拷贝UnityManifest序列化文件
|
||||||
|
{
|
||||||
|
string sourcePath = $"{pipelineOutputDirectory}/{YooAssetSettings.OutputFolderName}";
|
||||||
|
string destPath = $"{packageOutputDirectory}/{YooAssetSettings.OutputFolderName}";
|
||||||
|
EditorTools.CopyFile(sourcePath, destPath, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拷贝UnityManifest文本文件
|
||||||
|
{
|
||||||
|
string sourcePath = $"{pipelineOutputDirectory}/{YooAssetSettings.OutputFolderName}.manifest";
|
||||||
|
string destPath = $"{packageOutputDirectory}/{YooAssetSettings.OutputFolderName}.manifest";
|
||||||
|
EditorTools.CopyFile(sourcePath, destPath, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拷贝所有补丁文件
|
||||||
|
int progressValue = 0;
|
||||||
|
int fileTotalCount = buildMapContext.Collection.Count;
|
||||||
|
foreach (var bundleInfo in buildMapContext.Collection)
|
||||||
|
{
|
||||||
|
EditorTools.CopyFile(bundleInfo.PackageSourceFilePath, bundleInfo.PackageDestFilePath, true);
|
||||||
|
EditorTools.DisplayProgressBar("拷贝补丁文件", ++progressValue, fileTotalCount);
|
||||||
|
}
|
||||||
|
EditorTools.ClearProgressBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d110092f543e3fe40a4d3882e1a718e8
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,229 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[TaskAttribute("创建构建报告文件")]
|
||||||
|
public class TaskCreateReport : IBuildTask
|
||||||
|
{
|
||||||
|
void IBuildTask.Run(BuildContext context)
|
||||||
|
{
|
||||||
|
var buildParameters = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||||
|
var manifestContext = context.GetContextObject<ManifestContext>();
|
||||||
|
|
||||||
|
var buildMode = buildParameters.Parameters.BuildMode;
|
||||||
|
if (buildMode != EBuildMode.SimulateBuild)
|
||||||
|
{
|
||||||
|
CreateReportFile(buildParameters, buildMapContext, manifestContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateReportFile(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext, ManifestContext manifestContext)
|
||||||
|
{
|
||||||
|
var buildParameters = buildParametersContext.Parameters;
|
||||||
|
|
||||||
|
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
|
||||||
|
PackageManifest manifest = manifestContext.Manifest;
|
||||||
|
BuildReport buildReport = new BuildReport();
|
||||||
|
|
||||||
|
// 概述信息
|
||||||
|
{
|
||||||
|
#if UNITY_2019_4_OR_NEWER
|
||||||
|
UnityEditor.PackageManager.PackageInfo packageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssembly(typeof(BuildReport).Assembly);
|
||||||
|
if (packageInfo != null)
|
||||||
|
buildReport.Summary.YooVersion = packageInfo.version;
|
||||||
|
#endif
|
||||||
|
buildReport.Summary.UnityVersion = UnityEngine.Application.unityVersion;
|
||||||
|
buildReport.Summary.BuildDate = DateTime.Now.ToString();
|
||||||
|
buildReport.Summary.BuildSeconds = BuildRunner.TotalSeconds;
|
||||||
|
buildReport.Summary.BuildTarget = buildParameters.BuildTarget;
|
||||||
|
buildReport.Summary.BuildPipeline = buildParameters.BuildPipeline;
|
||||||
|
buildReport.Summary.BuildMode = buildParameters.BuildMode;
|
||||||
|
buildReport.Summary.BuildPackageName = buildParameters.PackageName;
|
||||||
|
buildReport.Summary.BuildPackageVersion = buildParameters.PackageVersion;
|
||||||
|
buildReport.Summary.EnableAddressable = buildMapContext.Command.EnableAddressable;
|
||||||
|
buildReport.Summary.LocationToLower = buildMapContext.Command.LocationToLower;
|
||||||
|
buildReport.Summary.IncludeAssetGUID = buildMapContext.Command.IncludeAssetGUID;
|
||||||
|
buildReport.Summary.UniqueBundleName = buildMapContext.Command.UniqueBundleName;
|
||||||
|
buildReport.Summary.SharedPackRuleClassName = buildParameters.SharedPackRule == null ?
|
||||||
|
"null" : buildParameters.SharedPackRule.GetType().FullName;
|
||||||
|
buildReport.Summary.EncryptionServicesClassName = buildParameters.EncryptionServices == null ?
|
||||||
|
"null" : buildParameters.EncryptionServices.GetType().FullName;
|
||||||
|
|
||||||
|
// 构建参数
|
||||||
|
buildReport.Summary.OutputNameStyle = buildParameters.OutputNameStyle;
|
||||||
|
buildReport.Summary.CompressOption = buildParameters.CompressOption;
|
||||||
|
buildReport.Summary.DisableWriteTypeTree = buildParameters.DisableWriteTypeTree;
|
||||||
|
buildReport.Summary.IgnoreTypeTreeChanges = buildParameters.IgnoreTypeTreeChanges;
|
||||||
|
|
||||||
|
// 构建结果
|
||||||
|
buildReport.Summary.AssetFileTotalCount = buildMapContext.AssetFileCount;
|
||||||
|
buildReport.Summary.MainAssetTotalCount = GetMainAssetCount(manifest);
|
||||||
|
buildReport.Summary.AllBundleTotalCount = GetAllBundleCount(manifest);
|
||||||
|
buildReport.Summary.AllBundleTotalSize = GetAllBundleSize(manifest);
|
||||||
|
buildReport.Summary.EncryptedBundleTotalCount = GetEncryptedBundleCount(manifest);
|
||||||
|
buildReport.Summary.EncryptedBundleTotalSize = GetEncryptedBundleSize(manifest);
|
||||||
|
buildReport.Summary.RawBundleTotalCount = GetRawBundleCount(manifest);
|
||||||
|
buildReport.Summary.RawBundleTotalSize = GetRawBundleSize(manifest);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 资源对象列表
|
||||||
|
buildReport.AssetInfos = new List<ReportAssetInfo>(manifest.AssetList.Count);
|
||||||
|
foreach (var packageAsset in manifest.AssetList)
|
||||||
|
{
|
||||||
|
var mainBundle = manifest.BundleList[packageAsset.BundleID];
|
||||||
|
ReportAssetInfo reportAssetInfo = new ReportAssetInfo();
|
||||||
|
reportAssetInfo.Address = packageAsset.Address;
|
||||||
|
reportAssetInfo.AssetPath = packageAsset.AssetPath;
|
||||||
|
reportAssetInfo.AssetTags = packageAsset.AssetTags;
|
||||||
|
reportAssetInfo.AssetGUID = AssetDatabase.AssetPathToGUID(packageAsset.AssetPath);
|
||||||
|
reportAssetInfo.MainBundleName = mainBundle.BundleName;
|
||||||
|
reportAssetInfo.MainBundleSize = mainBundle.FileSize;
|
||||||
|
reportAssetInfo.DependBundles = GetDependBundles(manifest, packageAsset);
|
||||||
|
reportAssetInfo.DependAssets = GetDependAssets(buildMapContext, mainBundle.BundleName, packageAsset.AssetPath);
|
||||||
|
buildReport.AssetInfos.Add(reportAssetInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 资源包列表
|
||||||
|
buildReport.BundleInfos = new List<ReportBundleInfo>(manifest.BundleList.Count);
|
||||||
|
foreach (var packageBundle in manifest.BundleList)
|
||||||
|
{
|
||||||
|
ReportBundleInfo reportBundleInfo = new ReportBundleInfo();
|
||||||
|
reportBundleInfo.BundleName = packageBundle.BundleName;
|
||||||
|
reportBundleInfo.FileName = packageBundle.FileName;
|
||||||
|
reportBundleInfo.FileHash = packageBundle.FileHash;
|
||||||
|
reportBundleInfo.FileCRC = packageBundle.FileCRC;
|
||||||
|
reportBundleInfo.FileSize = packageBundle.FileSize;
|
||||||
|
reportBundleInfo.IsRawFile = packageBundle.IsRawFile;
|
||||||
|
reportBundleInfo.LoadMethod = (EBundleLoadMethod)packageBundle.LoadMethod;
|
||||||
|
reportBundleInfo.Tags = packageBundle.Tags;
|
||||||
|
reportBundleInfo.ReferenceIDs = packageBundle.ReferenceIDs;
|
||||||
|
reportBundleInfo.AllBuiltinAssets = GetAllBuiltinAssets(buildMapContext, packageBundle.BundleName);
|
||||||
|
buildReport.BundleInfos.Add(reportBundleInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 冗余资源列表
|
||||||
|
buildReport.RedundancyInfos = new List<ReportRedundancyInfo>(buildMapContext.RedundancyInfos);
|
||||||
|
|
||||||
|
// 序列化文件
|
||||||
|
string fileName = YooAssetSettingsData.GetReportFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||||
|
string filePath = $"{packageOutputDirectory}/{fileName}";
|
||||||
|
BuildReport.Serialize(filePath, buildReport);
|
||||||
|
BuildLogger.Log($"资源构建报告文件创建完成:{filePath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取资源对象依赖的所有资源包
|
||||||
|
/// </summary>
|
||||||
|
private List<string> GetDependBundles(PackageManifest manifest, PackageAsset packageAsset)
|
||||||
|
{
|
||||||
|
List<string> dependBundles = new List<string>(packageAsset.DependIDs.Length);
|
||||||
|
foreach (int index in packageAsset.DependIDs)
|
||||||
|
{
|
||||||
|
string dependBundleName = manifest.BundleList[index].BundleName;
|
||||||
|
dependBundles.Add(dependBundleName);
|
||||||
|
}
|
||||||
|
return dependBundles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取资源对象依赖的其它所有资源
|
||||||
|
/// </summary>
|
||||||
|
private List<string> GetDependAssets(BuildMapContext buildMapContext, string bundleName, string assetPath)
|
||||||
|
{
|
||||||
|
List<string> result = new List<string>();
|
||||||
|
var bundleInfo = buildMapContext.GetBundleInfo(bundleName);
|
||||||
|
{
|
||||||
|
BuildAssetInfo findAssetInfo = null;
|
||||||
|
foreach (var assetInfo in bundleInfo.AllMainAssets)
|
||||||
|
{
|
||||||
|
if (assetInfo.AssetPath == assetPath)
|
||||||
|
{
|
||||||
|
findAssetInfo = assetInfo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (findAssetInfo == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"Not found asset {assetPath} in bunlde {bundleName}");
|
||||||
|
}
|
||||||
|
foreach (var dependAssetInfo in findAssetInfo.AllDependAssetInfos)
|
||||||
|
{
|
||||||
|
result.Add(dependAssetInfo.AssetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取该资源包内的所有资源
|
||||||
|
/// </summary>
|
||||||
|
private List<string> GetAllBuiltinAssets(BuildMapContext buildMapContext, string bundleName)
|
||||||
|
{
|
||||||
|
var bundleInfo = buildMapContext.GetBundleInfo(bundleName);
|
||||||
|
return bundleInfo.GetAllBuiltinAssetPaths();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetMainAssetCount(PackageManifest manifest)
|
||||||
|
{
|
||||||
|
return manifest.AssetList.Count;
|
||||||
|
}
|
||||||
|
private int GetAllBundleCount(PackageManifest manifest)
|
||||||
|
{
|
||||||
|
return manifest.BundleList.Count;
|
||||||
|
}
|
||||||
|
private long GetAllBundleSize(PackageManifest manifest)
|
||||||
|
{
|
||||||
|
long fileBytes = 0;
|
||||||
|
foreach (var packageBundle in manifest.BundleList)
|
||||||
|
{
|
||||||
|
fileBytes += packageBundle.FileSize;
|
||||||
|
}
|
||||||
|
return fileBytes;
|
||||||
|
}
|
||||||
|
private int GetEncryptedBundleCount(PackageManifest manifest)
|
||||||
|
{
|
||||||
|
int fileCount = 0;
|
||||||
|
foreach (var packageBundle in manifest.BundleList)
|
||||||
|
{
|
||||||
|
if (packageBundle.LoadMethod != (byte)EBundleLoadMethod.Normal)
|
||||||
|
fileCount++;
|
||||||
|
}
|
||||||
|
return fileCount;
|
||||||
|
}
|
||||||
|
private long GetEncryptedBundleSize(PackageManifest manifest)
|
||||||
|
{
|
||||||
|
long fileBytes = 0;
|
||||||
|
foreach (var packageBundle in manifest.BundleList)
|
||||||
|
{
|
||||||
|
if (packageBundle.LoadMethod != (byte)EBundleLoadMethod.Normal)
|
||||||
|
fileBytes += packageBundle.FileSize;
|
||||||
|
}
|
||||||
|
return fileBytes;
|
||||||
|
}
|
||||||
|
private int GetRawBundleCount(PackageManifest manifest)
|
||||||
|
{
|
||||||
|
int fileCount = 0;
|
||||||
|
foreach (var packageBundle in manifest.BundleList)
|
||||||
|
{
|
||||||
|
if (packageBundle.IsRawFile)
|
||||||
|
fileCount++;
|
||||||
|
}
|
||||||
|
return fileCount;
|
||||||
|
}
|
||||||
|
private long GetRawBundleSize(PackageManifest manifest)
|
||||||
|
{
|
||||||
|
long fileBytes = 0;
|
||||||
|
foreach (var packageBundle in manifest.BundleList)
|
||||||
|
{
|
||||||
|
if (packageBundle.IsRawFile)
|
||||||
|
fileBytes += packageBundle.FileSize;
|
||||||
|
}
|
||||||
|
return fileBytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bd12814185b4c7044b0afd59f9c1c948
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[TaskAttribute("资源包加密")]
|
||||||
|
public class TaskEncryption : IBuildTask
|
||||||
|
{
|
||||||
|
void IBuildTask.Run(BuildContext context)
|
||||||
|
{
|
||||||
|
var buildParameters = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||||
|
|
||||||
|
var buildMode = buildParameters.Parameters.BuildMode;
|
||||||
|
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
|
||||||
|
{
|
||||||
|
EncryptingBundleFiles(buildParameters, buildMapContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加密文件
|
||||||
|
/// </summary>
|
||||||
|
private void EncryptingBundleFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext)
|
||||||
|
{
|
||||||
|
var encryptionServices = buildParametersContext.Parameters.EncryptionServices;
|
||||||
|
if (encryptionServices == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (encryptionServices.GetType() == typeof(EncryptionNone))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int progressValue = 0;
|
||||||
|
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
|
||||||
|
foreach (var bundleInfo in buildMapContext.Collection)
|
||||||
|
{
|
||||||
|
EncryptFileInfo fileInfo = new EncryptFileInfo();
|
||||||
|
fileInfo.BundleName = bundleInfo.BundleName;
|
||||||
|
fileInfo.FilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
|
||||||
|
|
||||||
|
var encryptResult = encryptionServices.Encrypt(fileInfo);
|
||||||
|
if (encryptResult.LoadMethod != EBundleLoadMethod.Normal)
|
||||||
|
{
|
||||||
|
// 注意:原生文件不支持加密
|
||||||
|
if (bundleInfo.IsRawFile)
|
||||||
|
{
|
||||||
|
BuildLogger.Warning($"Encryption not support raw file : {bundleInfo.BundleName}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}.encrypt";
|
||||||
|
FileUtility.WriteAllBytes(filePath, encryptResult.EncryptedData);
|
||||||
|
bundleInfo.EncryptedFilePath = filePath;
|
||||||
|
bundleInfo.LoadMethod = encryptResult.LoadMethod;
|
||||||
|
BuildLogger.Log($"Bundle文件加密完成:{filePath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 进度条
|
||||||
|
EditorTools.DisplayProgressBar("加密资源包", ++progressValue, buildMapContext.Collection.Count);
|
||||||
|
}
|
||||||
|
EditorTools.ClearProgressBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c78d471226b9c8d429a2d962370f480b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,229 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[TaskAttribute("获取资源构建内容")]
|
||||||
|
public class TaskGetBuildMap : IBuildTask
|
||||||
|
{
|
||||||
|
void IBuildTask.Run(BuildContext context)
|
||||||
|
{
|
||||||
|
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var buildMapContext = CreateBuildMap(buildParametersContext.Parameters);
|
||||||
|
context.SetContextObject(buildMapContext);
|
||||||
|
BuildLogger.Log("构建内容准备完毕!");
|
||||||
|
|
||||||
|
// 检测构建结果
|
||||||
|
CheckBuildMapContent(buildMapContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源构建上下文
|
||||||
|
/// </summary>
|
||||||
|
public BuildMapContext CreateBuildMap(BuildParameters buildParameters)
|
||||||
|
{
|
||||||
|
var buildMode = buildParameters.BuildMode;
|
||||||
|
var packageName = buildParameters.PackageName;
|
||||||
|
var sharedPackRule = buildParameters.SharedPackRule;
|
||||||
|
|
||||||
|
Dictionary<string, BuildAssetInfo> allBuildAssetInfoDic = new Dictionary<string, BuildAssetInfo>(1000);
|
||||||
|
|
||||||
|
// 1. 检测配置合法性
|
||||||
|
AssetBundleCollectorSettingData.Setting.CheckPackageConfigError(packageName);
|
||||||
|
|
||||||
|
// 2. 获取所有收集器收集的资源
|
||||||
|
var collectResult = AssetBundleCollectorSettingData.Setting.GetPackageAssets(buildMode, packageName);
|
||||||
|
List<CollectAssetInfo> allCollectAssetInfos = collectResult.CollectAssets;
|
||||||
|
|
||||||
|
// 3. 剔除未被引用的依赖项资源
|
||||||
|
RemoveZeroReferenceAssets(allCollectAssetInfos);
|
||||||
|
|
||||||
|
// 4. 录入所有收集器收集的资源
|
||||||
|
foreach (var collectAssetInfo in allCollectAssetInfos)
|
||||||
|
{
|
||||||
|
if (allBuildAssetInfoDic.ContainsKey(collectAssetInfo.AssetPath) == false)
|
||||||
|
{
|
||||||
|
var buildAssetInfo = new BuildAssetInfo(collectAssetInfo.CollectorType, collectAssetInfo.BundleName,
|
||||||
|
collectAssetInfo.Address, collectAssetInfo.AssetPath, collectAssetInfo.IsRawAsset);
|
||||||
|
buildAssetInfo.AddAssetTags(collectAssetInfo.AssetTags);
|
||||||
|
buildAssetInfo.AddBundleTags(collectAssetInfo.AssetTags);
|
||||||
|
allBuildAssetInfoDic.Add(collectAssetInfo.AssetPath, buildAssetInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"Should never get here !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 录入所有收集资源的依赖资源
|
||||||
|
foreach (var collectAssetInfo in allCollectAssetInfos)
|
||||||
|
{
|
||||||
|
string collectAssetBundleName = collectAssetInfo.BundleName;
|
||||||
|
foreach (var dependAssetPath in collectAssetInfo.DependAssets)
|
||||||
|
{
|
||||||
|
if (allBuildAssetInfoDic.ContainsKey(dependAssetPath))
|
||||||
|
{
|
||||||
|
allBuildAssetInfoDic[dependAssetPath].AddBundleTags(collectAssetInfo.AssetTags);
|
||||||
|
allBuildAssetInfoDic[dependAssetPath].AddReferenceBundleName(collectAssetBundleName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var buildAssetInfo = new BuildAssetInfo(dependAssetPath);
|
||||||
|
buildAssetInfo.AddBundleTags(collectAssetInfo.AssetTags);
|
||||||
|
buildAssetInfo.AddReferenceBundleName(collectAssetBundleName);
|
||||||
|
allBuildAssetInfoDic.Add(dependAssetPath, buildAssetInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 填充所有收集资源的依赖列表
|
||||||
|
foreach (var collectAssetInfo in allCollectAssetInfos)
|
||||||
|
{
|
||||||
|
var dependAssetInfos = new List<BuildAssetInfo>(collectAssetInfo.DependAssets.Count);
|
||||||
|
foreach (var dependAssetPath in collectAssetInfo.DependAssets)
|
||||||
|
{
|
||||||
|
if (allBuildAssetInfoDic.TryGetValue(dependAssetPath, out BuildAssetInfo value))
|
||||||
|
dependAssetInfos.Add(value);
|
||||||
|
else
|
||||||
|
throw new Exception("Should never get here !");
|
||||||
|
}
|
||||||
|
allBuildAssetInfoDic[collectAssetInfo.AssetPath].SetAllDependAssetInfos(dependAssetInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. 记录关键信息
|
||||||
|
BuildMapContext context = new BuildMapContext();
|
||||||
|
context.AssetFileCount = allBuildAssetInfoDic.Count;
|
||||||
|
context.Command = collectResult.Command;
|
||||||
|
|
||||||
|
// 8. 计算共享资源的包名
|
||||||
|
var command = collectResult.Command;
|
||||||
|
foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
|
||||||
|
{
|
||||||
|
buildAssetInfo.CalculateShareBundleName(sharedPackRule, command.UniqueBundleName, command.PackageName, command.ShadersBundleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9. 记录冗余资源
|
||||||
|
foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
|
||||||
|
{
|
||||||
|
if (buildAssetInfo.IsRedundancyAsset())
|
||||||
|
{
|
||||||
|
var redundancyInfo = new ReportRedundancyInfo();
|
||||||
|
redundancyInfo.AssetPath = buildAssetInfo.AssetPath;
|
||||||
|
redundancyInfo.AssetType = AssetDatabase.GetMainAssetTypeAtPath(buildAssetInfo.AssetPath).Name;
|
||||||
|
redundancyInfo.AssetGUID = AssetDatabase.AssetPathToGUID(buildAssetInfo.AssetPath);
|
||||||
|
redundancyInfo.FileSize = FileUtility.GetFileSize(buildAssetInfo.AssetPath);
|
||||||
|
redundancyInfo.Number = buildAssetInfo.GetReferenceBundleCount();
|
||||||
|
context.RedundancyInfos.Add(redundancyInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10. 移除不参与构建的资源
|
||||||
|
List<BuildAssetInfo> removeBuildList = new List<BuildAssetInfo>();
|
||||||
|
foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
|
||||||
|
{
|
||||||
|
if (buildAssetInfo.HasBundleName() == false)
|
||||||
|
removeBuildList.Add(buildAssetInfo);
|
||||||
|
}
|
||||||
|
foreach (var removeValue in removeBuildList)
|
||||||
|
{
|
||||||
|
allBuildAssetInfoDic.Remove(removeValue.AssetPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 11. 构建资源列表
|
||||||
|
var allPackAssets = allBuildAssetInfoDic.Values.ToList();
|
||||||
|
if (allPackAssets.Count == 0)
|
||||||
|
throw new Exception("构建的资源列表不能为空");
|
||||||
|
foreach (var assetInfo in allPackAssets)
|
||||||
|
{
|
||||||
|
context.PackAsset(assetInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
private void RemoveZeroReferenceAssets(List<CollectAssetInfo> allCollectAssetInfos)
|
||||||
|
{
|
||||||
|
// 1. 检测是否任何存在依赖资源
|
||||||
|
bool hasAnyDependCollector = false;
|
||||||
|
foreach (var collectAssetInfo in allCollectAssetInfos)
|
||||||
|
{
|
||||||
|
var collectorType = collectAssetInfo.CollectorType;
|
||||||
|
if (collectorType == ECollectorType.DependAssetCollector)
|
||||||
|
{
|
||||||
|
hasAnyDependCollector = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasAnyDependCollector == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 2. 获取所有主资源的依赖资源集合
|
||||||
|
HashSet<string> allDependAsset = new HashSet<string>();
|
||||||
|
foreach (var collectAssetInfo in allCollectAssetInfos)
|
||||||
|
{
|
||||||
|
var collectorType = collectAssetInfo.CollectorType;
|
||||||
|
if (collectorType == ECollectorType.MainAssetCollector || collectorType == ECollectorType.StaticAssetCollector)
|
||||||
|
{
|
||||||
|
foreach (var dependAsset in collectAssetInfo.DependAssets)
|
||||||
|
{
|
||||||
|
if (allDependAsset.Contains(dependAsset) == false)
|
||||||
|
allDependAsset.Add(dependAsset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 找出所有零引用的依赖资源集合
|
||||||
|
List<CollectAssetInfo> removeList = new List<CollectAssetInfo>();
|
||||||
|
foreach (var collectAssetInfo in allCollectAssetInfos)
|
||||||
|
{
|
||||||
|
var collectorType = collectAssetInfo.CollectorType;
|
||||||
|
if (collectorType == ECollectorType.DependAssetCollector)
|
||||||
|
{
|
||||||
|
if (allDependAsset.Contains(collectAssetInfo.AssetPath) == false)
|
||||||
|
removeList.Add(collectAssetInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 移除所有零引用的依赖资源
|
||||||
|
foreach (var removeValue in removeList)
|
||||||
|
{
|
||||||
|
BuildLogger.Log($"发现未被依赖的资源并自动移除 : {removeValue.AssetPath}");
|
||||||
|
allCollectAssetInfos.Remove(removeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检测构建结果
|
||||||
|
/// </summary>
|
||||||
|
private void CheckBuildMapContent(BuildMapContext buildMapContext)
|
||||||
|
{
|
||||||
|
foreach (var bundleInfo in buildMapContext.Collection)
|
||||||
|
{
|
||||||
|
// 注意:原生文件资源包只能包含一个原生文件
|
||||||
|
bool isRawFile = bundleInfo.IsRawFile;
|
||||||
|
if (isRawFile)
|
||||||
|
{
|
||||||
|
if (bundleInfo.AllMainAssets.Count != 1)
|
||||||
|
throw new Exception($"The bundle does not support multiple raw asset : {bundleInfo.BundleName}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注意:原生文件不能被其它资源文件依赖
|
||||||
|
foreach (var assetInfo in bundleInfo.AllMainAssets)
|
||||||
|
{
|
||||||
|
if (assetInfo.AllDependAssetInfos != null)
|
||||||
|
{
|
||||||
|
foreach (var dependAssetInfo in assetInfo.AllDependAssetInfos)
|
||||||
|
{
|
||||||
|
if (dependAssetInfo.IsRawAsset)
|
||||||
|
throw new Exception($"{assetInfo.AssetPath} can not depend raw asset : {dependAssetInfo.AssetPath}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: baee18c5c7b76584b90413bf20fdae9a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[TaskAttribute("资源构建准备工作")]
|
||||||
|
public class TaskPrepare : IBuildTask
|
||||||
|
{
|
||||||
|
void IBuildTask.Run(BuildContext context)
|
||||||
|
{
|
||||||
|
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var buildParameters = buildParametersContext.Parameters;
|
||||||
|
|
||||||
|
// 检测构建参数合法性
|
||||||
|
if (buildParameters.BuildTarget == BuildTarget.NoTarget)
|
||||||
|
throw new Exception("请选择目标平台!");
|
||||||
|
if (string.IsNullOrEmpty(buildParameters.PackageName))
|
||||||
|
throw new Exception("包裹名称不能为空!");
|
||||||
|
if (string.IsNullOrEmpty(buildParameters.PackageVersion))
|
||||||
|
throw new Exception("包裹版本不能为空!");
|
||||||
|
if (string.IsNullOrEmpty(buildParameters.BuildOutputRoot))
|
||||||
|
throw new Exception("构建输出的根目录为空!");
|
||||||
|
if (string.IsNullOrEmpty(buildParameters.StreamingAssetsRoot))
|
||||||
|
throw new Exception("内置资源根目录为空!");
|
||||||
|
|
||||||
|
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
|
||||||
|
{
|
||||||
|
if (buildParameters.SBPParameters == null)
|
||||||
|
throw new Exception($"{nameof(BuildParameters.SBPParameters)} is null !");
|
||||||
|
|
||||||
|
if (buildParameters.BuildMode == EBuildMode.DryRunBuild)
|
||||||
|
throw new Exception($"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.DryRunBuild)} build mode !");
|
||||||
|
|
||||||
|
if (buildParameters.BuildMode == EBuildMode.ForceRebuild)
|
||||||
|
throw new Exception($"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.ForceRebuild)} build mode !");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buildParameters.BuildMode != EBuildMode.SimulateBuild)
|
||||||
|
{
|
||||||
|
#if UNITY_2021_3_OR_NEWER
|
||||||
|
if (buildParameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
|
||||||
|
{
|
||||||
|
BuildLogger.Warning("推荐使用可编程构建管线(SBP)!");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 检测当前是否正在构建资源包
|
||||||
|
if (BuildPipeline.isBuildingPlayer)
|
||||||
|
throw new Exception("当前正在构建资源包,请结束后再试");
|
||||||
|
|
||||||
|
// 检测是否有未保存场景
|
||||||
|
if (EditorTools.HasDirtyScenes())
|
||||||
|
throw new Exception("检测到未保存的场景文件");
|
||||||
|
|
||||||
|
// 检测首包资源标签
|
||||||
|
if (buildParameters.CopyBuildinFileOption == ECopyBuildinFileOption.ClearAndCopyByTags
|
||||||
|
|| buildParameters.CopyBuildinFileOption == ECopyBuildinFileOption.OnlyCopyByTags)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(buildParameters.CopyBuildinFileTags))
|
||||||
|
throw new Exception("首包资源标签不能为空!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测共享资源打包规则
|
||||||
|
if (buildParameters.SharedPackRule == null)
|
||||||
|
throw new Exception("共享资源打包规则不能为空!");
|
||||||
|
|
||||||
|
#if UNITY_WEBGL
|
||||||
|
if (buildParameters.EncryptionServices != null)
|
||||||
|
{
|
||||||
|
if (buildParameters.EncryptionServices.GetType() != typeof(EncryptionNone))
|
||||||
|
{
|
||||||
|
throw new Exception("WebGL平台不支持加密!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 检测包裹输出目录是否存在
|
||||||
|
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
|
||||||
|
if (Directory.Exists(packageOutputDirectory))
|
||||||
|
throw new Exception($"本次构建的补丁目录已经存在:{packageOutputDirectory}");
|
||||||
|
|
||||||
|
// 保存改动的资源
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buildParameters.BuildMode == EBuildMode.ForceRebuild)
|
||||||
|
{
|
||||||
|
string packageRootDirectory = buildParametersContext.GetPackageRootDirectory();
|
||||||
|
if (EditorTools.DeleteDirectory(packageRootDirectory))
|
||||||
|
{
|
||||||
|
BuildLogger.Log($"删除包裹目录:{packageRootDirectory}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果输出目录不存在
|
||||||
|
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
|
||||||
|
if (EditorTools.CreateDirectory(pipelineOutputDirectory))
|
||||||
|
{
|
||||||
|
BuildLogger.Log($"创建输出目录:{pipelineOutputDirectory}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0dee755cccd608d48b6581ec33c99b39
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,154 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[TaskAttribute("更新资源包信息")]
|
||||||
|
public class TaskUpdateBundleInfo : IBuildTask
|
||||||
|
{
|
||||||
|
void IBuildTask.Run(BuildContext context)
|
||||||
|
{
|
||||||
|
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||||
|
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
|
||||||
|
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
|
||||||
|
int outputNameStyle = (int)buildParametersContext.Parameters.OutputNameStyle;
|
||||||
|
|
||||||
|
// 1.检测文件名长度
|
||||||
|
foreach (var bundleInfo in buildMapContext.Collection)
|
||||||
|
{
|
||||||
|
// NOTE:检测文件名长度不要超过260字符。
|
||||||
|
string fileName = bundleInfo.BundleName;
|
||||||
|
if (fileName.Length >= 260)
|
||||||
|
throw new Exception($"The output bundle name is too long {fileName.Length} chars : {fileName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.更新构建输出的文件路径
|
||||||
|
foreach (var bundleInfo in buildMapContext.Collection)
|
||||||
|
{
|
||||||
|
bundleInfo.BuildOutputFilePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
|
||||||
|
if (bundleInfo.IsEncryptedFile)
|
||||||
|
bundleInfo.PackageSourceFilePath = bundleInfo.EncryptedFilePath;
|
||||||
|
else
|
||||||
|
bundleInfo.PackageSourceFilePath = bundleInfo.BuildOutputFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3.更新文件其它信息
|
||||||
|
foreach (var bundleInfo in buildMapContext.Collection)
|
||||||
|
{
|
||||||
|
bundleInfo.PackageUnityHash = GetUnityHash(bundleInfo, context);
|
||||||
|
bundleInfo.PackageUnityCRC = GetUnityCRC(bundleInfo, context);
|
||||||
|
bundleInfo.PackageFileHash = GetBundleFileHash(bundleInfo.PackageSourceFilePath, buildParametersContext);
|
||||||
|
bundleInfo.PackageFileCRC = GetBundleFileCRC(bundleInfo.PackageSourceFilePath, buildParametersContext);
|
||||||
|
bundleInfo.PackageFileSize = GetBundleFileSize(bundleInfo.PackageSourceFilePath, buildParametersContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4.更新补丁包输出的文件路径
|
||||||
|
foreach (var bundleInfo in buildMapContext.Collection)
|
||||||
|
{
|
||||||
|
string bundleName = bundleInfo.BundleName;
|
||||||
|
string fileHash = bundleInfo.PackageFileHash;
|
||||||
|
string fileExtension = ManifestTools.GetRemoteBundleFileExtension(bundleName);
|
||||||
|
string fileName = ManifestTools.GetRemoteBundleFileName(outputNameStyle, bundleName, fileExtension, fileHash);
|
||||||
|
bundleInfo.PackageDestFilePath = $"{packageOutputDirectory}/{fileName}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetUnityHash(BuildBundleInfo bundleInfo, BuildContext context)
|
||||||
|
{
|
||||||
|
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var parameters = buildParametersContext.Parameters;
|
||||||
|
var buildMode = parameters.BuildMode;
|
||||||
|
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
|
||||||
|
return "00000000000000000000000000000000"; //32位
|
||||||
|
|
||||||
|
if (bundleInfo.IsRawFile)
|
||||||
|
{
|
||||||
|
string filePath = bundleInfo.PackageSourceFilePath;
|
||||||
|
return HashUtility.FileMD5(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
|
||||||
|
{
|
||||||
|
var buildResult = context.GetContextObject<TaskBuilding.BuildResultContext>();
|
||||||
|
var hash = buildResult.UnityManifest.GetAssetBundleHash(bundleInfo.BundleName);
|
||||||
|
if (hash.isValid)
|
||||||
|
return hash.ToString();
|
||||||
|
else
|
||||||
|
throw new Exception($"Not found bundle hash in build result : {bundleInfo.BundleName}");
|
||||||
|
}
|
||||||
|
else if (parameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
|
||||||
|
{
|
||||||
|
// 注意:当资源包的依赖列表发生变化的时候,ContentHash也会发生变化!
|
||||||
|
var buildResult = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
|
||||||
|
if (buildResult.Results.BundleInfos.TryGetValue(bundleInfo.BundleName, out var value))
|
||||||
|
return value.Hash.ToString();
|
||||||
|
else
|
||||||
|
throw new Exception($"Not found bundle hash in build result : {bundleInfo.BundleName}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private uint GetUnityCRC(BuildBundleInfo bundleInfo, BuildContext context)
|
||||||
|
{
|
||||||
|
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var parameters = buildParametersContext.Parameters;
|
||||||
|
var buildMode = parameters.BuildMode;
|
||||||
|
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (bundleInfo.IsRawFile)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (parameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
|
||||||
|
{
|
||||||
|
string filePath = bundleInfo.BuildOutputFilePath;
|
||||||
|
if (BuildPipeline.GetCRCForAssetBundle(filePath, out uint crc))
|
||||||
|
return crc;
|
||||||
|
else
|
||||||
|
throw new Exception($"Not found bundle crc in build result : {bundleInfo.BundleName}");
|
||||||
|
}
|
||||||
|
else if (parameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
|
||||||
|
{
|
||||||
|
var buildResult = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
|
||||||
|
if (buildResult.Results.BundleInfos.TryGetValue(bundleInfo.BundleName, out var value))
|
||||||
|
return value.Crc;
|
||||||
|
else
|
||||||
|
throw new Exception($"Not found bundle crc in build result : {bundleInfo.BundleName}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private string GetBundleFileHash(string filePath, BuildParametersContext buildParametersContext)
|
||||||
|
{
|
||||||
|
var buildMode = buildParametersContext.Parameters.BuildMode;
|
||||||
|
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
|
||||||
|
return "00000000000000000000000000000000"; //32位
|
||||||
|
else
|
||||||
|
return HashUtility.FileMD5(filePath);
|
||||||
|
}
|
||||||
|
private string GetBundleFileCRC(string filePath, BuildParametersContext buildParametersContext)
|
||||||
|
{
|
||||||
|
var buildMode = buildParametersContext.Parameters.BuildMode;
|
||||||
|
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
|
||||||
|
return "00000000"; //8位
|
||||||
|
else
|
||||||
|
return HashUtility.FileCRC32(filePath);
|
||||||
|
}
|
||||||
|
private long GetBundleFileSize(string filePath, BuildParametersContext buildParametersContext)
|
||||||
|
{
|
||||||
|
var buildMode = buildParametersContext.Parameters.BuildMode;
|
||||||
|
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return FileUtility.GetFileSize(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4882f54fbf0bcb04680fb581deae4889
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,137 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace YooAsset.Editor
|
||||||
|
{
|
||||||
|
[TaskAttribute("验证构建结果")]
|
||||||
|
public class TaskVerifyBuildResult : IBuildTask
|
||||||
|
{
|
||||||
|
void IBuildTask.Run(BuildContext context)
|
||||||
|
{
|
||||||
|
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
|
||||||
|
|
||||||
|
// 模拟构建模式下跳过验证
|
||||||
|
if (buildParametersContext.Parameters.BuildMode == EBuildMode.SimulateBuild)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 验证构建结果
|
||||||
|
if (buildParametersContext.Parameters.VerifyBuildingResult)
|
||||||
|
{
|
||||||
|
var buildResultContext = context.GetContextObject<TaskBuilding.BuildResultContext>();
|
||||||
|
VerifyingBuildingResult(context, buildResultContext.UnityManifest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证构建结果
|
||||||
|
/// </summary>
|
||||||
|
private void VerifyingBuildingResult(BuildContext context, AssetBundleManifest unityManifest)
|
||||||
|
{
|
||||||
|
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
|
||||||
|
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||||
|
string[] unityCreateBundles = unityManifest.GetAllAssetBundles();
|
||||||
|
|
||||||
|
// 1. 过滤掉原生Bundle
|
||||||
|
string[] mapBundles = buildMapContext.Collection.Where(t => t.IsRawFile == false).Select(t => t.BundleName).ToArray();
|
||||||
|
|
||||||
|
// 2. 验证Bundle
|
||||||
|
List<string> exceptBundleList1 = unityCreateBundles.Except(mapBundles).ToList();
|
||||||
|
if (exceptBundleList1.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var exceptBundle in exceptBundleList1)
|
||||||
|
{
|
||||||
|
BuildLogger.Warning($"差异资源包: {exceptBundle}");
|
||||||
|
}
|
||||||
|
throw new System.Exception("存在差异资源包!请查看警告信息!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 验证Bundle
|
||||||
|
List<string> exceptBundleList2 = mapBundles.Except(unityCreateBundles).ToList();
|
||||||
|
if (exceptBundleList2.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var exceptBundle in exceptBundleList2)
|
||||||
|
{
|
||||||
|
BuildLogger.Warning($"差异资源包: {exceptBundle}");
|
||||||
|
}
|
||||||
|
throw new System.Exception("存在差异资源包!请查看警告信息!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 验证Asset
|
||||||
|
/*
|
||||||
|
bool isPass = true;
|
||||||
|
var buildMode = buildParametersContext.Parameters.BuildMode;
|
||||||
|
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
|
||||||
|
{
|
||||||
|
int progressValue = 0;
|
||||||
|
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
|
||||||
|
foreach (var buildedBundle in buildedBundles)
|
||||||
|
{
|
||||||
|
string filePath = $"{pipelineOutputDirectory}/{buildedBundle}";
|
||||||
|
string[] buildedAssetPaths = GetAssetBundleAllAssets(filePath);
|
||||||
|
string[] mapAssetPaths = buildMapContext.GetBuildinAssetPaths(buildedBundle);
|
||||||
|
if (mapAssetPaths.Length != buildedAssetPaths.Length)
|
||||||
|
{
|
||||||
|
BuildLogger.Warning($"构建的Bundle文件内的资源对象数量和预期不匹配 : {buildedBundle}");
|
||||||
|
var exceptAssetList1 = mapAssetPaths.Except(buildedAssetPaths).ToList();
|
||||||
|
foreach (var excpetAsset in exceptAssetList1)
|
||||||
|
{
|
||||||
|
BuildLogger.Warning($"构建失败的资源对象路径为 : {excpetAsset}");
|
||||||
|
}
|
||||||
|
var exceptAssetList2 = buildedAssetPaths.Except(mapAssetPaths).ToList();
|
||||||
|
foreach (var excpetAsset in exceptAssetList2)
|
||||||
|
{
|
||||||
|
BuildLogger.Warning($"构建失败的资源对象路径为 : {excpetAsset}");
|
||||||
|
}
|
||||||
|
isPass = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EditorTools.DisplayProgressBar("验证构建结果", ++progressValue, buildedBundles.Length);
|
||||||
|
}
|
||||||
|
EditorTools.ClearProgressBar();
|
||||||
|
|
||||||
|
if (isPass == false)
|
||||||
|
{
|
||||||
|
throw new Exception("构建结果验证没有通过,请参考警告日志!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
BuildLogger.Log("构建结果验证成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析.manifest文件并获取资源列表
|
||||||
|
/// </summary>
|
||||||
|
private string[] GetAssetBundleAllAssets(string filePath)
|
||||||
|
{
|
||||||
|
string manifestFilePath = $"{filePath}.manifest";
|
||||||
|
List<string> assetLines = new List<string>();
|
||||||
|
using (StreamReader reader = File.OpenText(manifestFilePath))
|
||||||
|
{
|
||||||
|
string content;
|
||||||
|
bool findTarget = false;
|
||||||
|
while (null != (content = reader.ReadLine()))
|
||||||
|
{
|
||||||
|
if (content.StartsWith("Dependencies:"))
|
||||||
|
break;
|
||||||
|
if (findTarget == false && content.StartsWith("Assets:"))
|
||||||
|
findTarget = true;
|
||||||
|
if (findTarget)
|
||||||
|
{
|
||||||
|
if (content.StartsWith("- "))
|
||||||
|
{
|
||||||
|
string assetPath = content.TrimStart("- ".ToCharArray());
|
||||||
|
assetLines.Add(assetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return assetLines.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue