Exemple #1
0
        /// <summary>
        /// 检测所有损坏的预制体文件
        /// </summary>
        public static void CheckCorruptionPrefab()
        {
            // 获取所有的打包路径
            List <string> collectDirectorys = AssetBundleCollectorSettingData.GetAllCollectDirectory();

            if (collectDirectorys.Count == 0)
            {
                throw new Exception("打包路径列表不能为空");
            }

            // 获取所有资源列表
            int checkCount   = 0;
            int invalidCount = 0;

            string[] findAssets = EditorTools.FindAssets(EAssetSearchType.Prefab, collectDirectorys.ToArray());
            foreach (string assetPath in findAssets)
            {
                UnityEngine.Object prefab = AssetDatabase.LoadAssetAtPath(assetPath, typeof(UnityEngine.Object));
                if (prefab == null)
                {
                    invalidCount++;
                    Debug.LogError($"发现损坏预制件:{assetPath}");
                }
                EditorTools.DisplayProgressBar("检测预制件文件是否损坏", ++checkCount, findAssets.Length);
            }
            EditorTools.ClearProgressBar();

            if (invalidCount == 0)
            {
                Debug.Log($"没有发现损坏预制件");
            }
        }
        private void OnDrawDLC()
        {
            // 列表显示
            EditorGUILayout.Space();
            EditorGUILayout.LabelField($"[ DLC ]");
            for (int i = 0; i < AssetBundleCollectorSettingData.Setting.DLCFiles.Count; i++)
            {
                string filePath = AssetBundleCollectorSettingData.Setting.DLCFiles[i];
                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField(filePath);
                    if (GUILayout.Button("-", GUILayout.MaxWidth(40)))
                    {
                        AssetBundleCollectorSettingData.RemoveDLC(filePath);
                        break;
                    }
                }
                EditorGUILayout.EndHorizontal();
            }

            // 添加按钮
            if (GUILayout.Button("+"))
            {
                string resultPath = EditorTools.OpenFilePath("Select File", "Assets/");
                if (resultPath != null)
                {
                    string filePath = EditorTools.AbsolutePathToAssetPath(resultPath);
                    AssetBundleCollectorSettingData.AddDLC(filePath);
                }
            }
        }
Exemple #3
0
 public AssetInfo(string assetPath)
 {
     AssetPath      = assetPath;
     IsCollectAsset = AssetBundleCollectorSettingData.IsCollectAsset(assetPath);
     IsSceneAsset   = AssetDatabase.GetMainAssetTypeAtPath(assetPath) == typeof(SceneAsset);
     IsVideoAsset   = AssetDatabase.GetMainAssetTypeAtPath(assetPath) == typeof(UnityEngine.Video.VideoClip);
 }
Exemple #4
0
        private void OnDrawShader()
        {
            bool   isCollectAllShader = AssetBundleCollectorSettingData.Setting.IsCollectAllShaders;
            string shadersBundleName  = AssetBundleCollectorSettingData.Setting.ShadersBundleName;

            EditorGUILayout.Space();

            bool newToggleValue = EditorGUILayout.Toggle("收集所有着色器", isCollectAllShader);

            if (newToggleValue != isCollectAllShader)
            {
                isCollectAllShader = newToggleValue;
                AssetBundleCollectorSettingData.ModifyShader(isCollectAllShader, shadersBundleName);
            }

            if (isCollectAllShader)
            {
                string newTextValue = EditorGUILayout.TextField("AssetBundle名称", shadersBundleName, GUILayout.MaxWidth(300));
                if (newTextValue != shadersBundleName)
                {
                    shadersBundleName = newTextValue;
                    AssetBundleCollectorSettingData.ModifyShader(isCollectAllShader, shadersBundleName);
                }
            }
        }
        void IBuildTask.Run(BuildContext context)
        {
            var buildParameters = context.GetContextObject <AssetBundleBuilder.BuildParametersContext>();
            var buildOptions    = context.GetContextObject <AssetBundleBuilder.BuildOptionsContext>();

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

            // 检测构建版本是否合法
            if (EditorTools.IsNumber(buildParameters.BuildVersion.ToString()) == false)
            {
                throw new Exception($"版本号格式非法:{buildParameters.BuildVersion}");
            }
            if (buildParameters.BuildVersion < 0)
            {
                throw new Exception("请先设置版本号");
            }

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

            // 检测补丁包是否已经存在
            string packageDirectory = buildParameters.GetPackageDirectory();

            if (Directory.Exists(packageDirectory))
            {
                throw new Exception($"补丁包已经存在:{packageDirectory}");
            }

            // 检测资源收集配置文件
            if (AssetBundleCollectorSettingData.GetCollecterCount() == 0)
            {
                throw new Exception("配置的资源收集路径为空!");
            }

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

            // 如果输出目录不存在
            if (EditorTools.CreateDirectory(buildParameters.OutputDirectory))
            {
                BuildLogger.Log($"创建输出目录:{buildParameters.OutputDirectory}");
            }
        }
        private void OnDrawCollector()
        {
            // 列表显示
            EditorGUILayout.Space();
            EditorGUILayout.LabelField($"[ Collector ]");
            for (int i = 0; i < AssetBundleCollectorSettingData.Setting.Collectors.Count; i++)
            {
                var    collector       = AssetBundleCollectorSettingData.Setting.Collectors[i];
                string directory       = collector.CollectDirectory;
                string labelClassName  = collector.LabelClassName;
                string filterClassName = collector.FilterClassName;

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField(directory);

                    // 标签类
                    {
                        int index    = LabelClassNameToIndex(labelClassName);
                        int newIndex = EditorGUILayout.Popup(index, _labelClassArray, GUILayout.MaxWidth(150));
                        if (newIndex != index)
                        {
                            labelClassName = IndexToLabelClassName(newIndex);
                            AssetBundleCollectorSettingData.ModifyCollector(directory, labelClassName, filterClassName);
                        }
                    }

                    // 过滤类
                    {
                        int index    = FilterClassNameToIndex(filterClassName);
                        int newIndex = EditorGUILayout.Popup(index, _filterClassArray, GUILayout.MaxWidth(150));
                        if (newIndex != index)
                        {
                            filterClassName = IndexToFilterClassName(newIndex);
                            AssetBundleCollectorSettingData.ModifyCollector(directory, labelClassName, filterClassName);
                        }
                    }

                    if (GUILayout.Button("-", GUILayout.MaxWidth(40)))
                    {
                        AssetBundleCollectorSettingData.RemoveCollector(directory);
                        break;
                    }
                }
                EditorGUILayout.EndHorizontal();
            }

            // 添加按钮
            if (GUILayout.Button("+"))
            {
                string resultPath = EditorTools.OpenFolderPanel("Select Folder", _lastOpenFolderPath);
                if (resultPath != null)
                {
                    _lastOpenFolderPath = EditorTools.AbsolutePathToAssetPath(resultPath);
                    AssetBundleCollectorSettingData.AddCollector(_lastOpenFolderPath);
                }
            }
        }
Exemple #7
0
        private void Init()
        {
            List <string> packRuleClassNames = AssetBundleCollectorSettingData.GetPackRuleClassNames();

            _packRuleClassArray = packRuleClassNames.ToArray();

            List <string> filterRuleClassNames = AssetBundleCollectorSettingData.GetFilterRuleClassNames();

            _filterRuleClassArray = filterRuleClassNames.ToArray();
        }
        private void Init()
        {
            List <string> labelClassNames = AssetBundleCollectorSettingData.GetLabelClassNames();

            _labelClassArray = labelClassNames.ToArray();

            List <string> filterClassNames = AssetBundleCollectorSettingData.GetFilterClassNames();

            _filterClassArray = filterClassNames.ToArray();
        }
        /// <summary>
        /// 执行构建
        /// </summary>
        public void PostAssetBuild()
        {
            Debug.Log("------------------------------OnPostAssetBuild------------------------------");

            // 检测工作
            if (AssetBundleCollectorSettingData.GetCollecterCount() == 0)
            {
                throw new Exception("[BuildPatch] 配置的资源收集路径为空!");
            }

            // 准备工作
            List <AssetInfo> buildMap = GetBuildMap();

            if (buildMap.Count == 0)
            {
                throw new Exception("[BuildPatch] 构建列表不能为空");
            }

            Log($"构建列表里总共有{buildMap.Count}个资源需要构建");
            List <AssetBundleBuild> buildInfoList = new List <AssetBundleBuild>(buildMap.Count);

            for (int i = 0; i < buildMap.Count; i++)
            {
                AssetInfo        assetInfo = buildMap[i];
                AssetBundleBuild buildInfo = new AssetBundleBuild();
                buildInfo.assetBundleName    = assetInfo.AssetBundleLabel;
                buildInfo.assetBundleVariant = assetInfo.AssetBundleVariant;
                buildInfo.assetNames         = new string[] { assetInfo.AssetPath };
                buildInfoList.Add(buildInfo);
            }

            // 开始构建
            Log($"开始构建......");
            BuildAssetBundleOptions opt           = MakeBuildOptions();
            AssetBundleManifest     unityManifest = BuildPipeline.BuildAssetBundles(OutputDirectory, buildInfoList.ToArray(), opt, BuildTarget);

            if (unityManifest == null)
            {
                throw new Exception("[BuildPatch] 构建过程中发生错误!");
            }

            // 加密资源文件
            List <string> encryptList = EncryptFiles(unityManifest);

            // 1. 检测循环依赖
            CheckCycleDepend(unityManifest);
            // 2. 创建补丁文件
            CreatePatchManifestFile(unityManifest, buildMap, encryptList);
            // 3. 创建说明文件
            CreateReadmeFile(unityManifest);
            // 4. 复制更新文件
            CopyUpdateFiles();

            Log("构建完成!");
        }
 /// <summary>
 /// 加载所有DLC文件
 /// </summary>
 public void LoadAllDCL()
 {
     string[] files = AssetBundleCollectorSettingData.GetDLCFiles();
     for (int i = 0; i < files.Length; i++)
     {
         DLContent dlc = DLContent.Deserialize(files[i]);
         if (dlc != null)
         {
             _contents.Add(dlc);
         }
     }
 }
Exemple #11
0
        private void OnDrawElement()
        {
            // 列表显示
            EditorGUILayout.Space();
            EditorGUILayout.LabelField($"Collector");
            for (int i = 0; i < AssetBundleCollectorSettingData.Setting.Collectors.Count; i++)
            {
                string directory = AssetBundleCollectorSettingData.Setting.Collectors[i].CollectDirectory;
                AssetBundleCollectorSetting.ECollectRule packRule = AssetBundleCollectorSettingData.Setting.Collectors[i].CollectRule;
                string collectorName = AssetBundleCollectorSettingData.Setting.Collectors[i].CollectorName;

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField(directory);

                    AssetBundleCollectorSetting.ECollectRule newPackRule = (AssetBundleCollectorSetting.ECollectRule)EditorGUILayout.EnumPopup(packRule, GUILayout.MaxWidth(150));
                    if (newPackRule != packRule)
                    {
                        packRule = newPackRule;
                        AssetBundleCollectorSettingData.ModifyCollector(directory, packRule, collectorName);
                    }

                    int index    = NameToIndex(collectorName);
                    int newIndex = EditorGUILayout.Popup(index, _collectorClassArray, GUILayout.MaxWidth(150));
                    if (newIndex != index)
                    {
                        string newCollectorName = IndexToName(newIndex);
                        AssetBundleCollectorSettingData.ModifyCollector(directory, packRule, newCollectorName);
                    }

                    if (GUILayout.Button("-", GUILayout.MaxWidth(40)))
                    {
                        AssetBundleCollectorSettingData.RemoveCollector(directory);
                        break;
                    }
                }
                EditorGUILayout.EndHorizontal();
            }

            // 添加按钮
            if (GUILayout.Button("+"))
            {
                string resultPath = EditorTools.OpenFolderPanel("Select Folder", _lastOpenFolderPath);
                if (resultPath != null)
                {
                    _lastOpenFolderPath = EditorTools.AbsolutePathToAssetPath(resultPath);
                    AssetBundleCollectorSettingData.AddCollector(_lastOpenFolderPath);
                }
            }
        }
        private void OnGUI()
        {
            // 列表显示
            EditorGUILayout.Space();
            EditorGUILayout.LabelField($"Collection List");
            for (int i = 0; i < AssetBundleCollectorSettingData.Setting.Elements.Count; i++)
            {
                string folderPath = AssetBundleCollectorSettingData.Setting.Elements[i].FolderPath;
                AssetBundleCollectorSetting.EFolderPackRule  packRule  = AssetBundleCollectorSettingData.Setting.Elements[i].PackRule;
                AssetBundleCollectorSetting.EBundleLabelRule labelRule = AssetBundleCollectorSettingData.Setting.Elements[i].LabelRule;

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField(folderPath);

                    AssetBundleCollectorSetting.EFolderPackRule newPackRule = (AssetBundleCollectorSetting.EFolderPackRule)EditorGUILayout.EnumPopup(packRule, GUILayout.MaxWidth(150));
                    if (newPackRule != packRule)
                    {
                        packRule = newPackRule;
                        AssetBundleCollectorSettingData.ModifyElement(folderPath, packRule, labelRule);
                    }

                    AssetBundleCollectorSetting.EBundleLabelRule newLabelRule = (AssetBundleCollectorSetting.EBundleLabelRule)EditorGUILayout.EnumPopup(labelRule, GUILayout.MaxWidth(150));
                    if (newLabelRule != labelRule)
                    {
                        labelRule = newLabelRule;
                        AssetBundleCollectorSettingData.ModifyElement(folderPath, packRule, labelRule);
                    }

                    if (GUILayout.Button("-", GUILayout.MaxWidth(40)))
                    {
                        AssetBundleCollectorSettingData.RemoveElement(folderPath);
                        break;
                    }
                }
                EditorGUILayout.EndHorizontal();
            }

            // 添加按钮
            if (GUILayout.Button("+"))
            {
                string resultPath = EditorTools.OpenFolderPanel("+", _lastOpenFolderPath);
                if (resultPath != null)
                {
                    _lastOpenFolderPath = EditorTools.AbsolutePathToAssetPath(resultPath);
                    AssetBundleCollectorSettingData.AddElement(_lastOpenFolderPath);
                }
            }
        }
        /// <summary>
        /// 获取指定资源依赖的资源列表
        /// 注意:返回列表里已经包括主资源自己
        /// </summary>
        private List <AssetInfo> GetDependencies(string assetPath)
        {
            List <AssetInfo> depends = new List <AssetInfo>();

            string[] dependArray = AssetDatabase.GetDependencies(assetPath, true);
            foreach (string dependPath in dependArray)
            {
                if (AssetBundleCollectorSettingData.ValidateAsset(dependPath))
                {
                    AssetInfo assetInfo = new AssetInfo(dependPath);
                    depends.Add(assetInfo);
                }
            }
            return(depends);
        }
        /// <summary>
        /// 获取指定资源依赖的资源列表
        /// 注意:返回列表里已经包括主资源自己
        /// </summary>
        private List <AssetInfo> GetDependencies(string mainAssetPath)
        {
            List <AssetInfo> result = new List <AssetInfo>();

            string[] depends = AssetDatabase.GetDependencies(mainAssetPath, true);
            foreach (string assetPath in depends)
            {
                if (AssetBundleCollectorSettingData.IsValidateAsset(assetPath))
                {
                    AssetInfo assetInfo = new AssetInfo(assetPath);
                    result.Add(assetInfo);
                }
            }
            return(result);
        }
Exemple #15
0
        /// <summary>
        /// 清理无用的材质球属性
        /// </summary>
        private void ClearMaterialUnusedProperty()
        {
            // 获取所有的打包路径
            List <string> collectDirectorys = AssetBundleCollectorSettingData.GetAllCollectDirectory();

            if (collectDirectorys.Count == 0)
            {
                throw new Exception("[BuildPackage] 打包路径列表不能为空");
            }

            // 获取所有资源列表
            int checkCount   = 0;
            int removedCount = 0;

            string[] guids = AssetDatabase.FindAssets(string.Empty, collectDirectorys.ToArray());
            foreach (string guid in guids)
            {
                string assetPath = AssetDatabase.GUIDToAssetPath(guid);
                string ext       = System.IO.Path.GetExtension(assetPath);
                if (ext == $".{EAssetFileExtension.mat}")
                {
                    Material mat     = AssetDatabase.LoadAssetAtPath <Material>(assetPath);
                    bool     removed = EditorTools.ClearMaterialUnusedProperty(mat);
                    if (removed)
                    {
                        removedCount++;
                        Debug.LogWarning($"[Build] 材质球已被处理:{assetPath}");
                    }
                }

                // 进度条相关
                checkCount++;
                EditorUtility.DisplayProgressBar("进度", $"清理无用的材质球属性:{checkCount}/{guids.Length}", (float)checkCount / guids.Length);
            }

            EditorUtility.ClearProgressBar();
            if (removedCount == 0)
            {
                Debug.Log($"没有发现冗余的材质球属性");
            }
            else
            {
                AssetDatabase.SaveAssets();
            }
        }
Exemple #16
0
        /// <summary>
        /// 设置资源的标签和变种
        /// </summary>
        private void SetAssetBundleLabelAndVariant(AssetInfo assetInfo)
        {
            // 如果资源所在文件夹的名称包含后缀符号,则为变体资源
            string folderName = Path.GetDirectoryName(assetInfo.AssetPath);             // "Assets/Texture.HD/background.jpg" --> "Assets/Texture.HD"

            if (Path.HasExtension(folderName))
            {
                string extension = Path.GetExtension(folderName);
                string label     = AssetBundleCollectorSettingData.GetAssetBundleLabel(assetInfo.AssetPath);
                assetInfo.AssetBundleLabel   = label.Replace(extension, string.Empty);
                assetInfo.AssetBundleVariant = extension.Substring(1);
            }
            else
            {
                assetInfo.AssetBundleLabel   = AssetBundleCollectorSettingData.GetAssetBundleLabel(assetInfo.AssetPath);
                assetInfo.AssetBundleVariant = PatchDefine.AssetBundleDefaultVariant;
            }
        }
Exemple #17
0
        /// <summary>
        /// 检测预制件是否损坏
        /// </summary>
        private void CheckAllPrefabValid()
        {
            // 获取所有的打包路径
            List <string> collectDirectorys = AssetBundleCollectorSettingData.GetAllCollectDirectory();

            if (collectDirectorys.Count == 0)
            {
                throw new Exception("[BuildPackage] 打包路径列表不能为空");
            }

            // 获取所有资源列表
            int checkCount   = 0;
            int invalidCount = 0;

            string[] guids = AssetDatabase.FindAssets(string.Empty, collectDirectorys.ToArray());
            foreach (string guid in guids)
            {
                string assetPath = AssetDatabase.GUIDToAssetPath(guid);
                string ext       = System.IO.Path.GetExtension(assetPath);
                if (ext == $".{EAssetFileExtension.prefab}")
                {
                    UnityEngine.Object prefab = AssetDatabase.LoadAssetAtPath(assetPath, typeof(UnityEngine.Object));
                    if (prefab == null)
                    {
                        invalidCount++;
                        Debug.LogError($"[Build] 发现损坏预制件:{assetPath}");
                    }
                }

                // 进度条相关
                checkCount++;
                EditorUtility.DisplayProgressBar("进度", $"检测预制件文件是否损坏:{checkCount}/{guids.Length}", (float)checkCount / guids.Length);
            }

            EditorUtility.ClearProgressBar();
            if (invalidCount == 0)
            {
                Debug.Log($"没有发现损坏预制件");
            }
        }
Exemple #18
0
        /// <summary>
        /// 清理无用的材质球属性
        /// </summary>
        public static void ClearMaterialUnusedProperty()
        {
            // 获取所有的打包路径
            List <string> collectDirectorys = AssetBundleCollectorSettingData.GetAllCollectDirectory();

            if (collectDirectorys.Count == 0)
            {
                throw new Exception("打包路径列表不能为空");
            }

            // 获取所有资源列表
            int checkCount   = 0;
            int removedCount = 0;

            string[] findAssets = EditorTools.FindAssets(EAssetSearchType.Material, collectDirectorys.ToArray());
            foreach (string assetPath in findAssets)
            {
                Material mat     = AssetDatabase.LoadAssetAtPath <Material>(assetPath);
                bool     removed = EditorTools.ClearMaterialUnusedProperty(mat);
                if (removed)
                {
                    removedCount++;
                    Debug.LogWarning($"材质球已被处理:{assetPath}");
                }
                EditorTools.DisplayProgressBar("清理无用的材质球属性", ++checkCount, findAssets.Length);
            }
            EditorTools.ClearProgressBar();

            if (removedCount == 0)
            {
                Debug.Log($"没有发现冗余的材质球属性");
            }
            else
            {
                AssetDatabase.SaveAssets();
            }
        }
Exemple #19
0
        public static void ImportXmlConfig(string filePath)
        {
            if (File.Exists(filePath) == false)
            {
                throw new FileNotFoundException(filePath);
            }

            if (Path.GetExtension(filePath) != ".xml")
            {
                throw new Exception($"Only support xml : {filePath}");
            }

            List <CollectWrapper> wrappers = new List <CollectWrapper>();

            // 加载文件
            XmlDocument xml = new XmlDocument();

            xml.Load(filePath);

            // 解析文件
            XmlElement  root     = xml.DocumentElement;
            XmlNodeList nodeList = root.GetElementsByTagName(XmlCollector);

            if (nodeList.Count == 0)
            {
                throw new Exception($"Not found any {XmlCollector}");
            }
            foreach (XmlNode node in nodeList)
            {
                XmlElement collect            = node as XmlElement;
                string     directory          = collect.GetAttribute(XmlDirectory);
                string     packRuleName       = collect.GetAttribute(XmlPackRule);
                string     filterRuleName     = collect.GetAttribute(XmlFilterRule);
                string     dontWriteAssetPath = collect.GetAttribute(XmlDontWriteAssetPath);
                string     assetTags          = collect.GetAttribute(XmlAssetTags);

                if (Directory.Exists(directory) == false)
                {
                    throw new Exception($"Not found directory : {directory}");
                }

                if (collect.HasAttribute(XmlPackRule) == false)
                {
                    throw new Exception($"Not found attribute {XmlPackRule} in collector : {directory}");
                }
                if (collect.HasAttribute(XmlFilterRule) == false)
                {
                    throw new Exception($"Not found attribute {XmlFilterRule} in collector : {directory}");
                }
                if (collect.HasAttribute(XmlDontWriteAssetPath) == false)
                {
                    throw new Exception($"Not found attribute {XmlDontWriteAssetPath} in collector : {directory}");
                }
                if (collect.HasAttribute(XmlAssetTags) == false)
                {
                    throw new Exception($"Not found attribute {XmlAssetTags} in collector : {directory}");
                }

                if (AssetBundleCollectorSettingData.HasPackRuleName(packRuleName) == false)
                {
                    throw new Exception($"Invalid {nameof(IPackRule)} class type : {packRuleName}");
                }
                if (AssetBundleCollectorSettingData.HasFilterRuleName(filterRuleName) == false)
                {
                    throw new Exception($"Invalid {nameof(IFilterRule)} class type : {filterRuleName}");
                }

                bool           dontWriteAssetPathValue = StringConvert.StringToBool(dontWriteAssetPath);
                CollectWrapper collectWrapper          = new CollectWrapper(directory, packRuleName, filterRuleName, dontWriteAssetPathValue, assetTags);
                wrappers.Add(collectWrapper);
            }

            // 导入配置数据
            AssetBundleCollectorSettingData.ClearAllCollector();
            foreach (var wrapper in wrappers)
            {
                AssetBundleCollectorSettingData.AddCollector(wrapper.CollectDirectory, wrapper.PackRuleName, wrapper.FilterRuleName, wrapper.DontWriteAssetPath, wrapper.AssetTags, false);
            }

            // 保存配置数据
            AssetBundleCollectorSettingData.SaveFile();
            Debug.Log($"导入配置完毕,一共导入{wrappers.Count}个收集器。");
        }
        private static List <Material> GetAllMaterials()
        {
            int           progressValue = 0;
            List <string> allAssets     = new List <string>(1000);

            // 获取所有打包的资源
            List <AssetCollectInfo> allCollectInfos = AssetBundleCollectorSettingData.GetAllCollectAssets();
            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 List <AssetInfo> GetBuildAssets()
        {
            int progressBarCount = 0;
            Dictionary <string, AssetInfo> buildAssets = new Dictionary <string, AssetInfo>();

            // 1. 获取主动收集的资源
            List <string> allCollectAssets = AssetBundleCollectorSettingData.GetAllCollectAssets();

            // 2. 对收集的资源进行依赖分析
            foreach (string collectAssetPath in allCollectAssets)
            {
                List <AssetInfo> depends = GetDependencies(collectAssetPath);
                for (int i = 0; i < depends.Count; i++)
                {
                    AssetInfo assetInfo = depends[i];
                    if (buildAssets.ContainsKey(assetInfo.AssetPath))
                    {
                        buildAssets[assetInfo.AssetPath].DependCount++;
                    }
                    else
                    {
                        buildAssets.Add(assetInfo.AssetPath, assetInfo);
                    }

                    // 注意:检测是否为主动收集资源
                    if (assetInfo.AssetPath == collectAssetPath)
                    {
                        buildAssets[collectAssetPath].IsCollectAsset = true;
                    }
                }
                progressBarCount++;
                EditorUtility.DisplayProgressBar("进度", $"依赖文件分析:{progressBarCount}/{allCollectAssets.Count}", (float)progressBarCount / allCollectAssets.Count);
            }
            progressBarCount = 0;
            EditorUtility.ClearProgressBar();

            // 3. 移除零依赖的资源
            List <string> removeList = new List <string>();

            foreach (KeyValuePair <string, AssetInfo> pair in buildAssets)
            {
                if (pair.Value.IsCollectAsset)
                {
                    continue;
                }
                if (pair.Value.DependCount == 0)
                {
                    removeList.Add(pair.Value.AssetPath);
                }
            }
            for (int i = 0; i < removeList.Count; i++)
            {
                buildAssets.Remove(removeList[i]);
            }

            // 4. 设置资源标签和变种
            foreach (KeyValuePair <string, AssetInfo> pair in buildAssets)
            {
                var assetInfo             = pair.Value;
                var bundleLabelAndVariant = AssetBundleCollectorSettingData.GetBundleLabelAndVariant(assetInfo.AssetPath, assetInfo.AssetType);
                assetInfo.SetBundleLabelAndVariant(bundleLabelAndVariant.BundleLabel, bundleLabelAndVariant.BundleVariant);
                progressBarCount++;
                EditorUtility.DisplayProgressBar("进度", $"设置资源标签:{progressBarCount}/{buildAssets.Count}", (float)progressBarCount / buildAssets.Count);
            }
            EditorUtility.ClearProgressBar();

            // 5. 返回结果
            return(buildAssets.Values.ToList());
        }
Exemple #22
0
        /// <summary>
        /// 准备工作
        /// </summary>
        private List <AssetInfo> GetBuildMap()
        {
            int progressBarCount = 0;
            Dictionary <string, AssetInfo> allAsset = new Dictionary <string, AssetInfo>();

            // 获取所有的收集路径
            List <string> collectDirectorys = AssetBundleCollectorSettingData.GetAllCollectDirectory();

            if (collectDirectorys.Count == 0)
            {
                throw new Exception("[BuildPatch] 配置的资源收集路径为空");
            }

            // 获取所有资源
            string[] guids = AssetDatabase.FindAssets(string.Empty, collectDirectorys.ToArray());
            foreach (string guid in guids)
            {
                string mainAssetPath = AssetDatabase.GUIDToAssetPath(guid);
                if (AssetBundleCollectorSettingData.IsIgnoreAsset(mainAssetPath))
                {
                    continue;
                }
                if (ValidateAsset(mainAssetPath) == false)
                {
                    continue;
                }

                List <AssetInfo> depends = GetDependencies(mainAssetPath);
                for (int i = 0; i < depends.Count; i++)
                {
                    AssetInfo assetInfo = depends[i];
                    if (allAsset.ContainsKey(assetInfo.AssetPath))
                    {
                        allAsset[assetInfo.AssetPath].DependCount++;
                    }
                    else
                    {
                        allAsset.Add(assetInfo.AssetPath, assetInfo);
                    }
                }

                // 进度条
                progressBarCount++;
                EditorUtility.DisplayProgressBar("进度", $"依赖文件分析:{progressBarCount}/{guids.Length}", (float)progressBarCount / guids.Length);
            }
            EditorUtility.ClearProgressBar();
            progressBarCount = 0;

            // 移除零依赖的资源
            List <string> removeList = new List <string>();

            foreach (KeyValuePair <string, AssetInfo> pair in allAsset)
            {
                if (pair.Value.IsCollectAsset)
                {
                    continue;
                }
                if (pair.Value.DependCount == 0)
                {
                    removeList.Add(pair.Value.AssetPath);
                }
            }
            for (int i = 0; i < removeList.Count; i++)
            {
                allAsset.Remove(removeList[i]);
            }

            // 设置资源标签
            foreach (KeyValuePair <string, AssetInfo> pair in allAsset)
            {
                SetAssetBundleLabelAndVariant(pair.Value);

                // 进度条
                progressBarCount++;
                EditorUtility.DisplayProgressBar("进度", $"设置资源标签:{progressBarCount}/{allAsset.Count}", (float)progressBarCount / allAsset.Count);
            }
            EditorUtility.ClearProgressBar();

            // 返回结果
            return(allAsset.Values.ToList());
        }
        /// <summary>
        /// 获取构建的资源列表
        /// </summary>
        private List <AssetInfo> GetBuildAssets()
        {
            Dictionary <string, AssetInfo> buildAssets = new Dictionary <string, AssetInfo>();
            Dictionary <string, string>    references  = new Dictionary <string, string>();

            // 1. 获取主动收集的资源
            List <AssetCollectInfo> allCollectAssets = AssetBundleCollectorSettingData.GetAllCollectAssets();

            // 2. 对收集的资源进行依赖分析
            int progressValue = 0;

            foreach (AssetCollectInfo collectInfo in allCollectAssets)
            {
                string           mainAssetPath = collectInfo.AssetPath;
                List <AssetInfo> depends       = GetDependencies(mainAssetPath);
                for (int i = 0; i < depends.Count; i++)
                {
                    AssetInfo assetInfo = depends[i];
                    string    assetPath = assetInfo.AssetPath;

                    // 如果已经存在,则增加该资源的依赖计数
                    if (buildAssets.ContainsKey(assetPath))
                    {
                        buildAssets[assetPath].DependCount++;
                    }
                    else
                    {
                        buildAssets.Add(assetPath, assetInfo);
                        references.Add(assetPath, mainAssetPath);
                    }

                    // 添加资源标记
                    buildAssets[assetPath].AddAssetTags(collectInfo.AssetTags);

                    // 注意:检测是否为主动收集资源
                    if (assetPath == mainAssetPath)
                    {
                        buildAssets[assetPath].IsCollectAsset     = true;
                        buildAssets[assetPath].DontWriteAssetPath = collectInfo.DontWriteAssetPath;
                    }
                }
                EditorTools.DisplayProgressBar("依赖文件分析", ++progressValue, allCollectAssets.Count);
            }
            EditorTools.ClearProgressBar();

            // 3. 移除零依赖的资源
            List <AssetInfo> undependentAssets = new List <AssetInfo>();

            foreach (KeyValuePair <string, AssetInfo> pair in buildAssets)
            {
                if (pair.Value.IsCollectAsset)
                {
                    continue;
                }
                if (pair.Value.DependCount == 0)
                {
                    undependentAssets.Add(pair.Value);
                }
            }
            foreach (var assetInfo in undependentAssets)
            {
                buildAssets.Remove(assetInfo.AssetPath);
            }

            // 4. 设置资源标签和变种
            progressValue = 0;
            foreach (KeyValuePair <string, AssetInfo> pair in buildAssets)
            {
                var assetInfo             = pair.Value;
                var bundleLabelAndVariant = AssetBundleCollectorSettingData.GetBundleLabelAndVariant(assetInfo.AssetPath);
                assetInfo.SetBundleLabelAndVariant(bundleLabelAndVariant.BundleLabel, bundleLabelAndVariant.BundleVariant);
                EditorTools.DisplayProgressBar("设置资源标签", ++progressValue, buildAssets.Count);
            }
            EditorTools.ClearProgressBar();

            // 5. 补充零依赖的资源
            foreach (var assetInfo in undependentAssets)
            {
                var referenceAssetPath = references[assetInfo.AssetPath];
                var referenceAssetInfo = buildAssets[referenceAssetPath];
                assetInfo.SetBundleLabelAndVariant(referenceAssetInfo.AssetBundleLabel, referenceAssetInfo.AssetBundleVariant);
                buildAssets.Add(assetInfo.AssetPath, assetInfo);
            }

            // 6. 返回结果
            return(buildAssets.Values.ToList());
        }
        void IBuildTask.Run(BuildContext context)
        {
            var buildParameters = context.GetContextObject <AssetBundleBuilder.BuildParametersContext>();

            // 检测构建平台是否合法
            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("输出目录不能为空");
            }

            // 检测资源收集配置文件
            if (AssetBundleCollectorSettingData.GetCollecterCount() == 0)
            {
                throw new Exception("配置的资源收集路径为空");
            }

            // 增量更新时候的必要检测
            if (buildParameters.Parameters.IsForceRebuild == false)
            {
                // 检测历史版本是否存在
                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}");
                }

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

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

            // 如果输出目录不存在
            if (EditorTools.CreateDirectory(buildParameters.PipelineOutputDirectory))
            {
                BuildLogger.Log($"创建输出目录:{buildParameters.PipelineOutputDirectory}");
            }
        }
Exemple #25
0
        private void Init()
        {
            List <string> names = AssetBundleCollectorSettingData.GetCollectorNames();

            _collectorClassArray = names.ToArray();
        }
        /// <summary>
        /// 准备工作
        /// </summary>
        private List <AssetInfo> GetBuildMap()
        {
            int progressBarCount = 0;
            Dictionary <string, AssetInfo> buildMap = new Dictionary <string, AssetInfo>();

            // 获取要收集的资源
            List <string> allCollectAssets = AssetBundleCollectorSettingData.GetAllCollectAssets();

            // 进行依赖分析
            foreach (string mainAssetPath in allCollectAssets)
            {
                List <AssetInfo> depends = GetDependencies(mainAssetPath);
                for (int i = 0; i < depends.Count; i++)
                {
                    AssetInfo assetInfo = depends[i];
                    if (buildMap.ContainsKey(assetInfo.AssetPath))
                    {
                        buildMap[assetInfo.AssetPath].DependCount++;
                    }
                    else
                    {
                        buildMap.Add(assetInfo.AssetPath, assetInfo);
                    }
                }
                progressBarCount++;
                EditorUtility.DisplayProgressBar("进度", $"依赖文件分析:{progressBarCount}/{allCollectAssets.Count}", (float)progressBarCount / allCollectAssets.Count);
            }
            EditorUtility.ClearProgressBar();
            progressBarCount = 0;

            // 移除零依赖的资源
            List <string> removeList = new List <string>();

            foreach (KeyValuePair <string, AssetInfo> pair in buildMap)
            {
                if (pair.Value.IsCollectAsset)
                {
                    continue;
                }
                if (pair.Value.DependCount == 0)
                {
                    removeList.Add(pair.Value.AssetPath);
                }
            }
            for (int i = 0; i < removeList.Count; i++)
            {
                buildMap.Remove(removeList[i]);
            }

            // 设置资源标签
            foreach (KeyValuePair <string, AssetInfo> pair in buildMap)
            {
                var assetInfo       = pair.Value;
                var labelAndVariant = AssetBundleCollectorSettingData.GetBundleLabelAndVariant(assetInfo.AssetPath);
                assetInfo.AssetBundleLabel   = labelAndVariant.BundleLabel;
                assetInfo.AssetBundleVariant = labelAndVariant.BundleVariant;
                progressBarCount++;
                EditorUtility.DisplayProgressBar("进度", $"设置资源标签:{progressBarCount}/{buildMap.Count}", (float)progressBarCount / buildMap.Count);
            }
            EditorUtility.ClearProgressBar();

            // 返回结果
            return(buildMap.Values.ToList());
        }
Exemple #27
0
        private void OnDrawCollector()
        {
            // 着色器选项
            EditorGUILayout.Space();
            bool isCollectAllShader = EditorGUILayout.Toggle("收集所有着色器", AssetBundleCollectorSettingData.Setting.IsCollectAllShaders);

            if (isCollectAllShader != AssetBundleCollectorSettingData.Setting.IsCollectAllShaders)
            {
                AssetBundleCollectorSettingData.ModifyShader(isCollectAllShader, AssetBundleCollectorSettingData.Setting.ShadersBundleName);
            }
            if (isCollectAllShader)
            {
                string shadersBundleName = EditorGUILayout.TextField("AssetBundle名称", AssetBundleCollectorSettingData.Setting.ShadersBundleName);
                if (shadersBundleName != AssetBundleCollectorSettingData.Setting.ShadersBundleName)
                {
                    AssetBundleCollectorSettingData.ModifyShader(isCollectAllShader, shadersBundleName);
                }
            }

            // 列表显示
            EditorGUILayout.Space();
            EditorGUILayout.LabelField($"[ Collector ]");
            _scrollPos = EditorGUILayout.BeginScrollView(_scrollPos);
            for (int i = 0; i < AssetBundleCollectorSettingData.Setting.Collectors.Count; i++)
            {
                var    collector           = AssetBundleCollectorSettingData.Setting.Collectors[i];
                string directory           = collector.CollectDirectory;
                string packRuleClassName   = collector.PackRuleClassName;
                string filterRuleClassName = collector.FilterRuleClassName;

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField(directory);

                    // IPackRule
                    {
                        int index    = PackRuleClassNameToIndex(packRuleClassName);
                        int newIndex = EditorGUILayout.Popup(index, _packRuleClassArray, GUILayout.MaxWidth(200));
                        if (newIndex != index)
                        {
                            packRuleClassName = IndexToPackRuleClassName(newIndex);
                            AssetBundleCollectorSettingData.ModifyCollector(directory, packRuleClassName, filterRuleClassName);
                        }
                    }

                    // IFilterRule
                    {
                        int index    = FilterRuleClassNameToIndex(filterRuleClassName);
                        int newIndex = EditorGUILayout.Popup(index, _filterRuleClassArray, GUILayout.MaxWidth(150));
                        if (newIndex != index)
                        {
                            filterRuleClassName = IndexToFilterRuleClassName(newIndex);
                            AssetBundleCollectorSettingData.ModifyCollector(directory, packRuleClassName, filterRuleClassName);
                        }
                    }

                    if (GUILayout.Button("-", GUILayout.MaxWidth(40)))
                    {
                        AssetBundleCollectorSettingData.RemoveCollector(directory);
                        break;
                    }
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndScrollView();

            // 添加按钮
            if (GUILayout.Button("+"))
            {
                string resultPath = EditorTools.OpenFolderPanel("Select Folder", _lastOpenFolderPath);
                if (resultPath != null)
                {
                    _lastOpenFolderPath = EditorTools.AbsolutePathToAssetPath(resultPath);
                    string defaultPackRuleClassName   = nameof(PackExplicit);
                    string defaultFilterRuleClassName = nameof(CollectAll);
                    AssetBundleCollectorSettingData.AddCollector(_lastOpenFolderPath, defaultPackRuleClassName, defaultFilterRuleClassName);
                }
            }

            // 导入配置按钮
            if (GUILayout.Button("Import Config"))
            {
                string resultPath = EditorTools.OpenFilePath("Select Folder", _lastOpenFolderPath);
                if (resultPath != null)
                {
                    CollectorConfigImporter.ImportXmlConfig(resultPath);
                }
            }
        }
Exemple #28
0
        private void OnDrawCollector()
        {
            // 列表显示
            EditorGUILayout.Space();
            _scrollPos = EditorGUILayout.BeginScrollView(_scrollPos);
            for (int i = 0; i < AssetBundleCollectorSettingData.Setting.Collectors.Count; i++)
            {
                var    collector          = AssetBundleCollectorSettingData.Setting.Collectors[i];
                string directory          = collector.CollectDirectory;
                string packRuleName       = collector.PackRuleName;
                string filterRuleName     = collector.FilterRuleName;
                bool   dontWriteAssetPath = collector.DontWriteAssetPath;
                string assetTags          = collector.AssetTags;

                EditorGUILayout.BeginHorizontal();
                {
                    // Directory
                    EditorGUILayout.LabelField(directory, GUILayout.MinWidth(GuiDirecotryMinSize), GUILayout.MaxWidth(GuiDirecotryMaxSize));

                    // IPackRule
                    {
                        int index    = PackRuleNameToIndex(packRuleName);
                        int newIndex = EditorGUILayout.Popup(index, _packRuleArray, GUILayout.MinWidth(GuiPackRuleSize), GUILayout.MaxWidth(GuiPackRuleSize));
                        if (newIndex != index)
                        {
                            packRuleName = IndexToPackRuleName(newIndex);
                            AssetBundleCollectorSettingData.ModifyCollector(directory, packRuleName, filterRuleName, dontWriteAssetPath, assetTags);
                        }
                    }

                    // IFilterRule
                    {
                        int index    = FilterRuleNameToIndex(filterRuleName);
                        int newIndex = EditorGUILayout.Popup(index, _filterRuleArray, GUILayout.MinWidth(GuiFilterRuleSize), GUILayout.MaxWidth(GuiFilterRuleSize));
                        if (newIndex != index)
                        {
                            filterRuleName = IndexToFilterRuleName(newIndex);
                            AssetBundleCollectorSettingData.ModifyCollector(directory, packRuleName, filterRuleName, dontWriteAssetPath, assetTags);
                        }
                    }

                    // DontWriteAssetPath
                    {
                        bool newToggleValue = EditorGUILayout.Toggle(dontWriteAssetPath, GUILayout.MinWidth(GuiDontWriteAssetPathSize), GUILayout.MaxWidth(GuiDontWriteAssetPathSize));
                        if (newToggleValue != dontWriteAssetPath)
                        {
                            dontWriteAssetPath = newToggleValue;
                            AssetBundleCollectorSettingData.ModifyCollector(directory, packRuleName, filterRuleName, dontWriteAssetPath, assetTags);
                        }
                    }

                    // AssetTags
                    {
                        string newTextValue = EditorGUILayout.TextField(assetTags, GUILayout.MinWidth(GuiAssetTagsMinSize), GUILayout.MaxWidth(GuiAssetTagsMaxSize));
                        if (newTextValue != assetTags)
                        {
                            assetTags = newTextValue;
                            AssetBundleCollectorSettingData.ModifyCollector(directory, packRuleName, filterRuleName, dontWriteAssetPath, assetTags);
                        }
                    }

                    if (GUILayout.Button("-", GUILayout.MinWidth(GuiBtnSize), GUILayout.MaxWidth(GuiBtnSize)))
                    {
                        AssetBundleCollectorSettingData.RemoveCollector(directory);
                        break;
                    }
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndScrollView();

            // 添加按钮
            if (GUILayout.Button("+"))
            {
                string resultPath = EditorTools.OpenFolderPanel("Select Folder", _lastOpenFolderPath);
                if (resultPath != null)
                {
                    _lastOpenFolderPath = EditorTools.AbsolutePathToAssetPath(resultPath);
                    string defaultPackRuleName            = nameof(PackExplicit);
                    string defaultFilterRuleName          = nameof(CollectAll);
                    bool   defaultDontWriteAssetPathValue = false;
                    string defaultAssetTag = string.Empty;
                    AssetBundleCollectorSettingData.AddCollector(_lastOpenFolderPath, defaultPackRuleName, defaultFilterRuleName, defaultDontWriteAssetPathValue, defaultAssetTag);
                }
            }

            // 导入配置按钮
            if (GUILayout.Button("Import Config"))
            {
                string resultPath = EditorTools.OpenFilePath("Select File", "Assets/", "xml");
                if (resultPath != null)
                {
                    CollectorConfigImporter.ImportXmlConfig(resultPath);
                }
            }
        }