Beispiel #1
0
 private List <Type> GetEncryptionServicesClassTypes()
 {
     return(EditorTools.GetAssignableTypes(typeof(IEncryptionServices)));
 }
Beispiel #2
0
        /// <summary>
        /// 加载配置文件
        /// </summary>
        private static void LoadSettingData()
        {
            _setting = EditorHelper.LoadSettingData <AssetBundleCollectorSetting>();

            // IPackRule
            {
                // 清空缓存集合
                _cachePackRuleTypes.Clear();
                _cachePackRuleInstance.Clear();

                // 获取所有类型
                List <Type> types = new List <Type>(100)
                {
                    typeof(PackSeparately),
                    typeof(PackDirectory),
                    typeof(PackTopDirectory),
                    typeof(PackCollector),
                    typeof(PackGroup),
                    typeof(PackRawFile),
                };

                var customTypes = EditorTools.GetAssignableTypes(typeof(IPackRule));
                types.AddRange(customTypes);
                for (int i = 0; i < types.Count; i++)
                {
                    Type type = types[i];
                    if (_cachePackRuleTypes.ContainsKey(type.Name) == false)
                    {
                        _cachePackRuleTypes.Add(type.Name, type);
                    }
                }
            }

            // IFilterRule
            {
                // 清空缓存集合
                _cacheFilterRuleTypes.Clear();
                _cacheFilterRuleInstance.Clear();

                // 获取所有类型
                List <Type> types = new List <Type>(100)
                {
                    typeof(CollectAll),
                    typeof(CollectScene),
                    typeof(CollectPrefab),
                    typeof(CollectSprite)
                };

                var customTypes = EditorTools.GetAssignableTypes(typeof(IFilterRule));
                types.AddRange(customTypes);
                for (int i = 0; i < types.Count; i++)
                {
                    Type type = types[i];
                    if (_cacheFilterRuleTypes.ContainsKey(type.Name) == false)
                    {
                        _cacheFilterRuleTypes.Add(type.Name, type);
                    }
                }
            }

            // IAddressRule
            {
                // 清空缓存集合
                _cacheAddressRuleTypes.Clear();
                _cacheAddressRuleInstance.Clear();

                // 获取所有类型
                List <Type> types = new List <Type>(100)
                {
                    typeof(AddressByFileName),
                    typeof(AddressByCollectorAndFileName),
                    typeof(AddressByGroupAndFileName)
                };

                var customTypes = EditorTools.GetAssignableTypes(typeof(IAddressRule));
                types.AddRange(customTypes);
                for (int i = 0; i < types.Count; i++)
                {
                    Type type = types[i];
                    if (_cacheAddressRuleTypes.ContainsKey(type.Name) == false)
                    {
                        _cacheAddressRuleTypes.Add(type.Name, type);
                    }
                }
            }
        }
 public static int GetCurrentShaderVariantCollectionVariantCount()
 {
     return((int)EditorTools.InvokeNonPublicStaticMethod(typeof(ShaderUtil), "GetCurrentShaderVariantCollectionVariantCount"));
 }
Beispiel #4
0
        void IBuildTask.Run(BuildContext context)
        {
            var buildParameters = context.GetContextObject <AssetBundleBuilder.BuildParametersContext>();

            buildParameters.BeginWatch();

            // 检测构建平台是否合法
            if (buildParameters.Parameters.BuildTarget == BuildTarget.NoTarget)
            {
                throw new Exception("请选择目标平台");
            }

            // 检测构建版本是否合法
            if (buildParameters.Parameters.BuildVersion <= 0)
            {
                throw new Exception("请先设置版本号");
            }

            // 检测输出目录是否为空
            if (string.IsNullOrEmpty(buildParameters.PipelineOutputDirectory))
            {
                throw new Exception("输出目录不能为空");
            }

            // 增量更新时候的必要检测
            var buildMode = buildParameters.Parameters.BuildMode;

            if (buildMode == EBuildMode.IncrementalBuild)
            {
                // 检测历史版本是否存在
                if (AssetBundleBuilderHelper.HasAnyPackageVersion(buildParameters.Parameters.BuildTarget, buildParameters.Parameters.OutputRoot) == false)
                {
                    throw new Exception("没有发现任何历史版本,请尝试强制重建");
                }

                // 检测构建版本是否合法
                int maxPackageVersion = AssetBundleBuilderHelper.GetMaxPackageVersion(buildParameters.Parameters.BuildTarget, buildParameters.Parameters.OutputRoot);
                if (buildParameters.Parameters.BuildVersion <= maxPackageVersion)
                {
                    throw new Exception("构建版本不能小于历史版本");
                }

                // 检测补丁包是否已经存在
                string packageDirectory = buildParameters.GetPackageDirectory();
                if (Directory.Exists(packageDirectory))
                {
                    throw new Exception($"补丁包已经存在:{packageDirectory}");
                }

                // 检测内置资源分类标签是否一致
                var oldPatchManifest = AssetBundleBuilderHelper.GetOldPatchManifest(buildParameters.PipelineOutputDirectory);
                if (buildParameters.Parameters.BuildinTags != oldPatchManifest.BuildinTags)
                {
                    throw new Exception($"增量更新时内置资源标签必须一致:{buildParameters.Parameters.BuildinTags} != {oldPatchManifest.BuildinTags}");
                }
            }

            // 如果是强制重建
            if (buildMode == EBuildMode.ForceRebuild)
            {
                // 删除平台总目录
                string platformDirectory = $"{buildParameters.Parameters.OutputRoot}/{buildParameters.Parameters.BuildTarget}";
                if (EditorTools.DeleteDirectory(platformDirectory))
                {
                    BuildRunner.Log($"删除平台总目录:{platformDirectory}");
                }
            }

            // 如果输出目录不存在
            if (EditorTools.CreateDirectory(buildParameters.PipelineOutputDirectory))
            {
                BuildRunner.Log($"创建输出目录:{buildParameters.PipelineOutputDirectory}");
            }
        }
 private static void SaveCurrentShaderVariantCollection()
 {
     EditorTools.InvokeNonPublicStaticMethod(typeof(ShaderUtil), "SaveCurrentShaderVariantCollection", _saveFilePath);
 }
 private static void ClearCurrentShaderVariantCollection()
 {
     EditorTools.InvokeNonPublicStaticMethod(typeof(ShaderUtil), "ClearCurrentShaderVariantCollection");
 }
        private static List <Material> GetAllMaterials()
        {
            int           progressValue = 0;
            List <string> allAssets     = new List <string>(1000);

            // 获取所有打包的资源
            List <CollectAssetInfo> allCollectInfos = AssetBundleCollectorSettingData.Setting.GetAllCollectAssets(EBuildMode.DryRunBuild);
            List <string>           collectAssets   = allCollectInfos.Select(t => t.AssetPath).ToList();

            foreach (var assetPath in collectAssets)
            {
                string[] depends = AssetDatabase.GetDependencies(assetPath, true);
                foreach (var depend in depends)
                {
                    if (allAssets.Contains(depend) == false)
                    {
                        allAssets.Add(depend);
                    }
                }
                EditorTools.DisplayProgressBar("获取所有打包资源", ++progressValue, collectAssets.Count);
            }
            EditorTools.ClearProgressBar();

            // 搜集所有材质球
            progressValue = 0;
            var shaderDic = new Dictionary <Shader, List <Material> >(100);

            foreach (var assetPath in allAssets)
            {
                System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
                if (assetType == typeof(UnityEngine.Material))
                {
                    var material = AssetDatabase.LoadAssetAtPath <Material>(assetPath);
                    var shader   = material.shader;
                    if (shader == null)
                    {
                        continue;
                    }

                    if (shaderDic.ContainsKey(shader) == false)
                    {
                        shaderDic.Add(shader, new List <Material>());
                    }
                    if (shaderDic[shader].Contains(material) == false)
                    {
                        shaderDic[shader].Add(material);
                    }
                }
                EditorTools.DisplayProgressBar("搜集所有材质球", ++progressValue, allAssets.Count);
            }
            EditorTools.ClearProgressBar();

            // 返回结果
            var materials = new List <Material>(1000);

            foreach (var valuePair in shaderDic)
            {
                materials.AddRange(valuePair.Value);
            }
            return(materials);
        }
        /// <summary>
        /// 验证构建结果
        /// </summary>
        private void VerifyingBuildingResult(BuildContext context, AssetBundleManifest unityManifest)
        {
            var buildParameters = context.GetContextObject <AssetBundleBuilder.BuildParametersContext>();
            var buildMapContext = context.GetContextObject <BuildMapContext>();

            string[] buildedBundles = unityManifest.GetAllAssetBundles();

            // 1. 过滤掉原生Bundle
            List <BuildBundleInfo> expectBundles = new List <BuildBundleInfo>(buildedBundles.Length);

            foreach (var bundleInfo in buildMapContext.BundleInfos)
            {
                if (bundleInfo.IsRawFile == false)
                {
                    expectBundles.Add(bundleInfo);
                }
            }

            // 2. 验证数量
            if (buildedBundles.Length != expectBundles.Count)
            {
                Debug.LogWarning($"构建过程中可能存在无效的资源,导致和预期构建的Bundle数量不一致!");
            }

            // 3. 正向验证Bundle
            foreach (var bundleName in buildedBundles)
            {
                if (buildMapContext.IsContainsBundle(bundleName) == false)
                {
                    throw new Exception($"Should never get here !");
                }
            }

            // 4. 反向验证Bundle
            bool isPass = true;

            foreach (var expectBundle in expectBundles)
            {
                bool isMatch = false;
                foreach (var buildedBundle in buildedBundles)
                {
                    if (buildedBundle == expectBundle.BundleName)
                    {
                        isMatch = true;
                        break;
                    }
                }
                if (isMatch == false)
                {
                    isPass = false;
                    Debug.LogWarning($"没有找到预期构建的Bundle文件 : {expectBundle.BundleName}");
                }
            }
            if (isPass == false)
            {
                throw new Exception("构建结果验证没有通过,请参考警告日志!");
            }

            // 5. 验证Asset
            var buildMode = buildParameters.Parameters.BuildMode;

            if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
            {
                int progressValue = 0;
                foreach (var buildedBundle in buildedBundles)
                {
                    string   filePath                = $"{buildParameters.PipelineOutputDirectory}/{buildedBundle}";
                    string[] allBuildinAssetPaths    = GetAssetBundleAllAssets(filePath);
                    string[] expectBuildinAssetPaths = buildMapContext.GetBuildinAssetPaths(buildedBundle);
                    if (expectBuildinAssetPaths.Length != allBuildinAssetPaths.Length)
                    {
                        Debug.LogWarning($"构建的Bundle文件内的资源对象数量和预期不匹配 : {buildedBundle}");
                        isPass = false;
                        continue;
                    }

                    foreach (var buildinAssetPath in allBuildinAssetPaths)
                    {
                        var guid = AssetDatabase.AssetPathToGUID(buildinAssetPath);
                        if (string.IsNullOrEmpty(guid))
                        {
                            Debug.LogWarning($"无效的资源路径,请检查路径是否带有特殊符号或中文:{buildinAssetPath}");
                            isPass = false;
                            continue;
                        }

                        bool isMatch = false;
                        foreach (var exceptBuildAssetPath in expectBuildinAssetPaths)
                        {
                            var guidExcept = AssetDatabase.AssetPathToGUID(exceptBuildAssetPath);
                            if (guid == guidExcept)
                            {
                                isMatch = true;
                                break;
                            }
                        }
                        if (isMatch == false)
                        {
                            Debug.LogWarning($"在构建的Bundle文件里发现了没有匹配的资源对象:{buildinAssetPath}");
                            isPass = false;
                            continue;
                        }
                    }

                    EditorTools.DisplayProgressBar("验证构建结果", ++progressValue, buildedBundles.Length);
                }
                EditorTools.ClearProgressBar();
                if (isPass == false)
                {
                    throw new Exception("构建结果验证没有通过,请参考警告日志!");
                }
            }

            // 卸载所有加载的Bundle
            BuildRunner.Log("构建结果验证成功!");
        }
        /// <summary>
        /// 获取打包收集的资源文件
        /// </summary>
        public List <CollectAssetInfo> GetAllCollectAssets(AssetBundleCollectorGroup group)
        {
            // 注意:模拟构建模式下只收集主资源
            if (AssetBundleCollectorSetting.BuildMode == EBuildMode.SimulateBuild)
            {
                if (CollectorType != ECollectorType.MainAssetCollector)
                {
                    return(new List <CollectAssetInfo>());
                }
            }

            Dictionary <string, CollectAssetInfo> result = new Dictionary <string, CollectAssetInfo>(1000);
            bool isRawAsset = PackRuleName == nameof(PackRawFile);

            // 检测原生资源包的收集器类型
            if (isRawAsset && CollectorType != ECollectorType.MainAssetCollector)
            {
                throw new Exception($"The raw file must be set to {nameof(ECollectorType)}.{ECollectorType.MainAssetCollector} : {CollectPath}");
            }

            if (string.IsNullOrEmpty(CollectPath))
            {
                throw new Exception($"The collect path is null or empty in group : {group.GroupName}");
            }

            // 收集打包资源
            if (AssetDatabase.IsValidFolder(CollectPath))
            {
                string   collectDirectory = CollectPath;
                string[] findAssets       = EditorTools.FindAssets(EAssetSearchType.All, collectDirectory);
                foreach (string assetPath in findAssets)
                {
                    if (IsValidateAsset(assetPath) && IsCollectAsset(assetPath))
                    {
                        if (result.ContainsKey(assetPath) == false)
                        {
                            var collectAssetInfo = CreateCollectAssetInfo(group, assetPath, isRawAsset);
                            result.Add(assetPath, collectAssetInfo);
                        }
                        else
                        {
                            throw new Exception($"The collecting asset file is existed : {assetPath} in collector : {CollectPath}");
                        }
                    }
                }
            }
            else
            {
                string assetPath = CollectPath;
                if (IsValidateAsset(assetPath) && IsCollectAsset(assetPath))
                {
                    var collectAssetInfo = CreateCollectAssetInfo(group, assetPath, isRawAsset);
                    result.Add(assetPath, collectAssetInfo);
                }
                else
                {
                    throw new Exception($"The collecting single asset file is invalid : {assetPath} in collector : {CollectPath}");
                }
            }

            // 检测可寻址地址是否重复
            if (AssetBundleCollectorSettingData.Setting.EnableAddressable)
            {
                HashSet <string> adressTemper = new HashSet <string>();
                foreach (var collectInfoPair in result)
                {
                    if (collectInfoPair.Value.CollectorType == ECollectorType.MainAssetCollector)
                    {
                        string address = collectInfoPair.Value.Address;
                        if (adressTemper.Contains(address) == false)
                        {
                            adressTemper.Add(address);
                        }
                        else
                        {
                            throw new Exception($"The address is existed : {address} in collector : {CollectPath}");
                        }
                    }
                }
            }

            // 返回列表
            return(result.Values.ToList());
        }