Пример #1
0
        public static void BuildRelation(StaticABSettings abSetting)
        {
            AssetCustomProcesses.Init();
            AssetNodeCollector.Clear();

            manualSettings = abSetting.Settings;
            s_specialAB    = new Dictionary <string, BundleUnloadStrategy>();
            foreach (var setting in manualSettings)
            {
                Debug.LogWarning($"Setting Path : {setting.Path}");
                var settingFiles = Directory.GetFiles(setting.Path, "*", SearchOption.AllDirectories);
                foreach (var filePath in settingFiles)
                {
                    if (Array.IndexOf(IgnoreExtensions, Path.GetExtension(filePath)) >= 0 || filePath.Contains(".svn"))
                    {
                        continue;
                    }
                    var abName        = string.Empty;
                    var directoryName = Path.GetDirectoryName(filePath) ?? "";
                    switch (setting.Op)
                    {
                    case StaticABSetting.Operation.ALL_IN_ONE:
                        abName = FormatPath(setting.Path);
                        break;

                    case StaticABSetting.Operation.STAY_RESOURCES:
                        break;

                    case StaticABSetting.Operation.EACH_FOLDER_ONE:
                        abName = FormatPath(directoryName);
                        break;

                    case StaticABSetting.Operation.EACH_A_AB:
                        abName = FormatPath(Path.Combine(directoryName, Path.GetFileNameWithoutExtension(filePath)));
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    var s    = Array.Find(setting.UnloadStrategies, strategy => strategy.BundleName == abName);
                    var node = AssetNode.GetOrCreate(filePath, abName);
                    // 同名资源处理
                    if (!s_specialAB.ContainsKey(node.AssetName))
                    {
                        s_specialAB.Add(node.AssetName, s?.UnloadStrategy ?? BundleUnloadStrategy.Normal);
                    }

                    if (Path.GetExtension(node.AssetPath) == ".spriteatlas")
                    {
                        var dependencies = AssetDatabase.GetDependencies(node.AssetPath);
                        foreach (var dependency in dependencies)
                        {
                            var depNode = AssetNode.GetOrCreate(dependency, abName);
                            if (Equals(depNode, node))
                            {
                                continue;
                            }

                            if (s_specialAB.ContainsKey(depNode.AssetName))
                            {
                                Debug.LogError($"one sprite in multi atlas : {depNode.AssetName}");
                                continue;
                            }

                            s_specialAB.Add(depNode.AssetName, s?.UnloadStrategy ?? BundleUnloadStrategy.Normal);
                        }
                        node.ForceAddToResourcesNode();
                    }
                }
            }

            var           resourcesFiles = Directory.GetFiles("Assets/Resources", "*", SearchOption.AllDirectories);
            List <string> filteredFiles  = new List <string>(resourcesFiles.Length);

            filteredFiles.AddRange(resourcesFiles.Where(file => !file.Contains(".svn") &&
                                                        Array.IndexOf(IgnoreExtensions, Path.GetExtension(file)) == -1));
            resourcesFiles = filteredFiles.ToArray();
            var otherFiles = new string[abSetting.ExtraDependencyAssets.Length];

            for (var i = 0; i < abSetting.ExtraDependencyAssets.Length; i++)
            {
                var asset = abSetting.ExtraDependencyAssets[i];
                var path  = AssetDatabase.GetAssetPath(asset);
                otherFiles[i] = path;
            }

            foreach (var sceneAsset in abSetting.Scenes)
            {
                if (!sceneAsset)
                {
                    Debug.LogError($"Scene asset is null");
                    continue;
                }
                var scenePath   = AssetDatabase.GetAssetPath(sceneAsset);
                var sceneAbName = scenePath.Substring(0, scenePath.Length - 6).ToLower();
                var sceneNode   = AssetNode.GetOrCreate(scenePath, sceneAbName);
                sceneNode.ForceAddToResourcesNode();
                var dependencies = AssetDatabase.GetDependencies(scenePath, false);
                foreach (var dependency in dependencies)
                {
                    if (Array.IndexOf(IgnoreExtensions, Path.GetExtension(dependency)) >= 0)
                    {
                        continue;
                    }

                    if (!dependency.StartsWith("assets", true, CultureInfo.InvariantCulture))
                    {
                        Debug.LogWarning($"{scenePath} Depend asset : {dependency} is not under Assets folder");
                        continue;
                    }
                    AssetNode.GetOrCreate(dependency, sceneAbName + "_scene");
                }
            }

            resourcesFiles = resourcesFiles.Concat(otherFiles).ToArray();
            EditorUtility.DisplayProgressBar("Process resources asset", "", 0);
            RelationProcess(resourcesFiles);
            AssetCustomProcesses.PostProcess();

            ExportResourcesPackageConf();
        }
Пример #2
0
        public static bool RebuildAllAssetBundles(BuildTarget target, bool appendLuaDir)
        {
            outputPath           = null;
            m_currentBuildTarget = target;
            InitializeSetting();
            BuildAssetRelation.Clear();
            var settings = settingRoot;

            if (appendLuaDir)
            {
                BuildLuaFile(Path.Combine(Application.dataPath.Replace("Assets", ""), "Lua"));
                AssetDatabase.Refresh();

                settings = CreateInstance <StaticABSettings>();
                settings.ExtraDependencyAssets = settingRoot.ExtraDependencyAssets;
                settings.Settings = new StaticABSetting[settingRoot.Settings.Length + 1];
                Array.Copy(settingRoot.Settings, settings.Settings, settingRoot.Settings.Length);
                settings.Settings[settingRoot.Settings.Length] = new StaticABSetting()
                {
                    FolderPath       = AssetDatabase.LoadAssetAtPath <DefaultAsset>("Assets/Resources/Lua"),
                    Op               = StaticABSetting.Operation.ALL_IN_ONE,
                    UnloadStrategies = new SpecialBundleLoadLogic[0]
                };
                settings.Scenes = settingRoot.Scenes;
                Debug.Log("Finish copy lua directory");
            }

            try {
                BuildAssetRelation.BuildRelation(settings);
                Debug.Log($"Start AB Build Output : {OutputPath}");

                var buildContext = AssetNodeCollector.Output();
                using (var stream = new StreamWriter("./build-relations.tsv")) {
                    for (int i = 0; i < buildContext.Length; i++)
                    {
                        var ctx = buildContext[i];
                        stream.WriteLine($"{i}\t{ctx.assetBundleName}\t{string.Join("\t", ctx.assetNames)}");
                    }
                }

                BuildPipeline.BuildAssetBundles(OutputPath, buildContext,
                                                BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.ChunkBasedCompression, target);
                Directory.Delete($"{Application.dataPath}/Resources/Lua", true);
                FinalClear();
                //处理之前先删除streamingAssetsPath内的内容,以免有冗余的旧ab包打进安装包
                if (Directory.Exists(CopyPath))
                {
                    Directory.Delete(CopyPath, true);
                    Directory.CreateDirectory(CopyPath);
                }

                foreach (var item in buildContext)
                {
                    string abBuildOutPath = Path.Combine(OutputPath, item.assetBundleName);
                    string nameStrHash    = item.assetBundleName.GetHashCode().ToString();
                    byte[] offsetData     = Encoding.UTF8.GetBytes(nameStrHash);
                    string targetPath     = Path.Combine(CopyPath, item.assetBundleName);
                    string directoryPath  = Path.GetDirectoryName(targetPath);
                    if (!Directory.Exists(directoryPath))
                    {
                        Directory.CreateDirectory(directoryPath ?? string.Empty);
                    }
                    using (var destFile = File.Open(targetPath, FileMode.OpenOrCreate, FileAccess.Write))
                        using (var sourceFile = new FileStream(abBuildOutPath, FileMode.Open)) {
                            destFile.Write(offsetData, 0, offsetData.Length);
                            var buffer = new byte[1024];
                            while (sourceFile.Position < sourceFile.Length)
                            {
                                var size = sourceFile.Read(buffer, 0, buffer.Length);
                                destFile.Write(buffer, 0, size);
                            }
                        }
                }

                File.Copy($"{OutputPath}/package.conf", $"{CopyPath}/package.conf", true);
                File.Copy($"{OutputPath}/{m_currentBuildTarget.ToString()}",
                          $"{CopyPath}/{m_currentBuildTarget.ToString()}", true);
                return(true);
            }
            catch (Exception e) {
                EditorUtility.ClearProgressBar();
                Debug.LogException(e);
                return(false);
            }
            finally {
                AssetCustomProcesses.Shutdown();
            }
        }