先拷贝之前的代码过来

main
ZhuoZhou 2025-04-18 15:35:35 +08:00
parent 49390bcf0c
commit 823a4bac52
586 changed files with 39067 additions and 57 deletions

138
.gitignore vendored
View File

@ -1,69 +1,93 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# This .gitignore file should be placed at the root of your Unity project directory
#
# Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore
#
/FindItBundleBuilder/[Ll]ibrary/
/FindItBundleBuilder/[Tt]emp/
/FindItBundleBuilder/[Oo]bj/
/FindItBundleBuilder/[Bb]uild/
/FindItBundleBuilder/[Bb]uilds/
/FindItBundleBuilder/[Ll]ogs/
/FindItBundleBuilder/[Uu]ser[Ss]ettings/
# C extensions
*.so
# MemoryCaptures can get excessive in size.
# They also could contain extremely sensitive data
/FindItBundleBuilder/[Mm]emoryCaptures/
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# Recordings can get excessive in size
/FindItBundleBuilder/[Rr]ecordings/
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Asset meta data should only be ignored when the corresponding asset is also ignored
!/FindItBundleBuilder/[Aa]ssets/**/*.meta
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Uncomment this line if you wish to ignore the asset store tools plugin
# /[Aa]ssets/AssetStoreTools*
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
# Autogenerated Jetbrains Rider plugin
/FindItBundleBuilder/[Aa]ssets/Plugins/Editor/JetBrains*
.idea/
# Translations
*.mo
*.pot
# Visual Studio cache directory
.vs/
# Django stuff:
*.log
# Gradle cache directory
.gradle/
# Sphinx documentation
docs/_build/
# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db
# PyBuilder
target/
# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
*.mdb.meta
.idea
Error.D2.Android
Error.D2.iOS
Log.D2
# Unity3D generated file on crash reports
sysinfo.txt
d2
atlas
atlas_remote_config.json
# Temporary auto-generated Android Assets
/FindItBundleBuilder/[Aa]ssets/[Ss]treamingAssets/aa.meta
/FindItBundleBuilder/[Aa]ssets/[Ss]treamingAssets/aa/*
# Builds
*.apk
*.unitypackage
/FindItBundleBuilder/BuildOutput/
# MacOS cache files
.DS_Store
.vscode
# Crashlytics generated file
crashlytics-build.properties
# project cache
AssetBundle
Assets/ABLevelAssets
ABLevelAssets.meta
remote_config_data
Assets/StreamingAssets/build_info
Assets/StreamingAssets/build_info.meta
Assets/StreamingAssets/
Assets/StreamingAssets.meta
Release/
FindItBundleBuilder/Bundles
FindItBundleBuilder/Assets/StreamingAssets
StreamingAssets.meta
__pycache__
remote_config.json
FindItBundleBuilder/Tools/config_convert/gen_file

View File

@ -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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fe4cb5ddc6c5d4769924469cce0011ed
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,101 @@
%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/animalparty
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:
- CollectPath: Assets/AssetRaw/UIRaw/Raw/Level/doodledelight
CollectorGUID: 2cfdbbca31c6c4620b97e5def3c5cf47
CollectorType: 0
AddressRuleName: AddressByFileName
PackRuleName: PackTopDirectory
FilterRuleName: CollectAll
AssetTags:
UserData:
- CollectPath: Assets/AssetRaw/UIRaw/Raw/Level/mysterymeow
CollectorGUID: 965d090bb8f0e4271b70e77e53039e18
CollectorType: 0
AddressRuleName: AddressByFileName
PackRuleName: PackTopDirectory
FilterRuleName: CollectAll
AssetTags:
UserData:
- CollectPath: Assets/AssetRaw/UIRaw/Raw/Level/retrocharm
CollectorGUID: 7b6ec4b6421864bfa897b0d241d38a8c
CollectorType: 0
AddressRuleName: AddressByFileName
PackRuleName: PackTopDirectory
FilterRuleName: CollectAll
AssetTags:
UserData:
- CollectPath: Assets/AssetRaw/UIRaw/Raw/Level/thesmiths
CollectorGUID: 250cbe2a1c5fb4266bca2cf02f7c914d
CollectorType: 0
AddressRuleName: AddressByFileName
PackRuleName: PackTopDirectory
FilterRuleName: CollectAll
AssetTags:
UserData:
- CollectPath: Assets/AssetRaw/UIRaw/Raw/Level/tidyup
CollectorGUID: 2b16ad3c8ad7542d786e8ae48fb2a1e7
CollectorType: 0
AddressRuleName: AddressByFileName
PackRuleName: PackTopDirectory
FilterRuleName: CollectAll
AssetTags:
UserData:
- CollectPath: Assets/AssetRaw/UIRaw/Raw/Level/trackhunt
CollectorGUID: 24f8efd523b9343e48a602fb442fd15b
CollectorType: 0
AddressRuleName: AddressByFileName
PackRuleName: PackTopDirectory
FilterRuleName: CollectAll
AssetTags:
UserData:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9e01483f3dd3c4f2abcbe9fbd3bb5a76
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a02d2cfa67b2346c889f631727b3e25e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 912e21748435b45fc997193d7c93ff90
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5098feb5dd4e44512bc57146f9e1a576
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: beffb292aca4344e1a423d7287fc3728
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1c17b617b71c34255ac4108d736950ed
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8c41414d13c2749c38819bf9f9c32257
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2cfdbbca31c6c4620b97e5def3c5cf47
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 965d090bb8f0e4271b70e77e53039e18
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7b6ec4b6421864bfa897b0d241d38a8c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 250cbe2a1c5fb4266bca2cf02f7c914d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2b16ad3c8ad7542d786e8ae48fb2a1e7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 24f8efd523b9343e48a602fb442fd15b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c2d4a782dcb034673a46135eff2152c3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9d956dabce56d4e18937ab68e94bb001
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d1c6e58c2c4694ec0bdb395afccacef4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3cc5406dc53c14e2190deaafcfa2bc33
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a8872076958014e08ad505763938381d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 83148db1cb56b4629b4b3113862fada8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 64b4e87dfb41744b89b9e872f1e79cae
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4540f0d639fb941f0840cf0c7fd6e61c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a6b00a5bbca684f8b8f5d9656d18f7a7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1 @@
项目AB资源软链接文件夹和资源工程文件夹名称保持一致

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3f1ca26670fc7465ea399367ef61f8e1
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f85f4e5a623742589d2e8496bbb1892f
timeCreated: 1702539544

View File

@ -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;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 987faa5215d04a7a84736a2514261cdb
timeCreated: 1703644705

View File

@ -0,0 +1,326 @@
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_"))
{
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);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5bd0d3c899424e118aa507af0ecf7149
timeCreated: 1702540933

View File

@ -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;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c469487362bc4eb0a8e5790325ec8a97
timeCreated: 1702885370

View File

@ -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;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7f274ff1cb324de49164268263e60e5c
timeCreated: 1702879548

View File

@ -0,0 +1,13 @@
public enum GamePlay
{
thesmiths = 0, //史密斯一家
retrocharm, //复古魅力
animalparty, //动物派对
trackhunt, //踪迹追寻
doodledelight, //快乐涂鸦
mysterymeow, //神秘猫咪
tidyup, //整理房间
colorfun, //填色乐趣
end, //始终放在最后
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2090a55aac6a473cb00da44087c5e38d
timeCreated: 1703643978

View File

@ -0,0 +1,77 @@
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));
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;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f1edd427ad4e459c9a855d93bfd17358
timeCreated: 1703641976

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9859ae1fa2f2c47b7bcf57daddd8f9c5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f4a3e18dc695146a5a8f27c16a4b7e9c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9a224b3ff275d4acc87b15420b9f2b44
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a5811114ae8414c40813b7de0df8375e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2cda990e2423bbf4892e6590ba056729
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: db680274cf006c548abff57b7e1894b4
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ac093515ae764b94aa07be91d4ba978b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1fdecc5500229d44887425ce619352fc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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();
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: de7563040250b4e4a835d1fc90238e38
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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}/";
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f48abdec05f0dbe438a83e181fe6bc93
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 09788b4733bab2d4792fdd5d28e7653c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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!");
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 24698266f028e4a47bb88f091fd64547
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 66e43420e95cd0b4bae8803a31e9817b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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>

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 28ba29adb4949284e8c48893218b0d9a
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}

View File

@ -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;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f94918fa1ea63c34fa0e49fdad4119cf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 447008dd110b8d746aafbe88c78bee5d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 826a9d7b4de0eba40b5c39b33747c011
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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);
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8229aa3f8a369204db5c368715191e2f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 98bb314dc26ba184fbb9e9fdcdb58a1d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b84510feab7cbe44a9b6d8ef0b3f559c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2875232ad7f87c148b752d432f3a54f2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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}");
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6a232601f99c4634ea17fca4979f80ab
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2bc82466a51f50141975e4424095aa09
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e0855c4b5eaa26942bd7ad177fe3c288
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 79014124da678684388454d6ea892722
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@

namespace YooAsset.Editor
{
public interface IBuildTask
{
void Run(BuildContext context);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8888657c45e12c646a8349bac6bf0326
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@

namespace YooAsset.Editor
{
public interface IContextObject
{
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 151a4acd5ad1c2046be20e080f9bdad4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 35749e57d9a3da84aa60c348bc6bbe9d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 254f430e0264bd84387878f8d7280e44
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f01d5c82be95c8f4b93aeefc0454ae5c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f38422f6a64300243af6b4fbf84644ba
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9466e826c135e994c84961e4b921ca5f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More