Пример #1
0
        public static void Build()
        {
            Clear();
            var Mods   = ModsEditor.GetMods();
            int length = Mods.Length;

            for (int i = 0; i < length; i++)
            {
                var ModInfo         = ModsEditor.GetModInfo(Mods[i]);
                var ModOutPutFolder = OutPutFolder + "/" + ModInfo.PackageName;
                Directory.CreateDirectory(ModOutPutFolder);

                //生成ModInfo文件
                using (StreamWriter sw = File.CreateText(ModOutPutFolder + "/" + ModInfo.PackageName + ".json"))
                {
                    sw.Write(JsonConvert.SerializeObject(ModInfo));
                }

                //Windows64版本构建
                //构建参数
                var param = new BundleBuildParameters(BuildTarget.StandaloneWindows64, BuildTargetGroup.Standalone, ModOutPutFolder);
                param.BundleCompression = BuildCompression.LZ4;
                //填入资源
                var content = new BundleBuildContent(new AssetBundleBuild[] { GetAllAssets(ModInfo, "winmod") });
                IBundleBuildResults results;
                //构建包
                ReturnCode code = ContentPipeline.BuildAssetBundles(param, content, out results);
                if (code != ReturnCode.Success)
                {
                    if (code == ReturnCode.Canceled)
                    {
                        return;//如果取消,直接返回
                    }
                    Debug.LogError("构建失败!错误原因:" + code.ToString());
                }
            }
        }
    public static ReturnCode BuildAssetBundles(string outputPath, CompressionType compressionMode, BuildTarget buildTarget, BuildTargetGroup buildGroup, out IBundleBuildResults results)
    {
        BundleBuildContent    buildContent = new BundleBuildContent(ContentBuildInterface.GenerateAssetBundleBuilds());
        BundleBuildParameters buildParams  = new BundleBuildParameters(buildTarget, buildGroup, outputPath);

        SetupBuildCacheServer(buildParams);

        switch (compressionMode)
        {
        case CompressionType.None:
            buildParams.BundleCompression = BuildCompression.Uncompressed;
            break;

        case CompressionType.Lz4:
            buildParams.BundleCompression = BuildCompression.LZ4;
            break;

        default:
            buildParams.BundleCompression = BuildCompression.LZMA;
            break;
        }

        return(ContentPipeline.BuildAssetBundles(buildParams, buildContent, out results));
    }
        public static void BuildAssetBundles(AssetbundleBuildSettings settings, BuildType buildType)
        {
            if (!Application.isBatchMode)
            {
                //have to ask save current scene
                var saved = UnityEditor.SceneManagement.EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo();

                if (!saved)
                {
                    EditorUtility.DisplayDialog("Build Failed!", $"User Canceled", "Confirm");
                    return;
                }
            }

            var bundleList = GetAssetBundlesList(settings);

            var buildTarget = EditorUserBuildSettings.activeBuildTarget;
            var groupTarget = BuildPipeline.GetBuildTargetGroup(buildTarget);

            var outputPath = Utility.CombinePath(buildType == BuildType.Local ? settings.LocalOutputPath : settings.RemoteOutputPath, buildTarget.ToString());


            //generate sharedBundle if needed, and pre generate dependency
            var treeResult = AssetDependencyTree.ProcessDependencyTree(bundleList);

            if (settings.AutoCreateSharedBundles)
            {
                bundleList.AddRange(treeResult.SharedBundles);
            }

            var buildParams = new CustomBuildParameters(settings, buildTarget, groupTarget, outputPath, treeResult.BundleDependencies, buildType);

            buildParams.UseCache = !settings.ForceRebuild;

            if (buildParams.UseCache && settings.UseCacheServer)
            {
                buildParams.CacheServerHost = settings.CacheServerHost;
                buildParams.CacheServerPort = settings.CacheServerPort;
            }

            ContentPipeline.BuildCallbacks.PostPackingCallback += PostPackingForSelectiveBuild;
            var returnCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(bundleList.ToArray()), out var results);

            ContentPipeline.BuildCallbacks.PostPackingCallback -= PostPackingForSelectiveBuild;


            if (returnCode == ReturnCode.Success)
            {
                //only remote bundle build generates link.xml
                switch (buildType)
                {
                case BuildType.Local:
                    WriteManifestFile(outputPath, results, buildTarget, settings.RemoteURL);
                    WriteLogFile(outputPath, results);
                    if (!Application.isBatchMode)
                    {
                        EditorUtility.DisplayDialog("Build Succeeded!", "Local bundle build succeeded!", "Confirm");
                    }
                    break;

                case BuildType.Remote:
                    WriteManifestFile(outputPath, results, buildTarget, settings.RemoteURL);
                    WriteLogFile(outputPath, results);
                    var linkPath = TypeLinkerGenerator.Generate(settings, results);
                    if (!Application.isBatchMode)
                    {
                        EditorUtility.DisplayDialog("Build Succeeded!", $"Remote bundle build succeeded, \n {linkPath} updated!", "Confirm");
                    }
                    if (settings.AutoUploadS3)
                    {
                        LocusAssetbundleUploaderExtension.UploadToS3Bucket(settings);
                    }
                    break;
                }
            }
            else
            {
                EditorUtility.DisplayDialog("Build Failed!", $"Bundle build failed, \n Code : {returnCode}", "Confirm");
                Debug.LogError(returnCode);
            }
        }
Пример #4
0
        /// <summary>
        /// The method that does the actual building after all the groups have been processed.
        /// </summary>
        /// <param name="builderInput">The generic builderInput of the</param>
        /// <param name="aaContext"></param>
        /// <typeparam name="TResult"></typeparam>
        /// <returns></returns>
        protected virtual TResult DoBuild <TResult>(AddressablesDataBuilderInput builderInput, AddressableAssetsBuildContext aaContext) where TResult : IDataBuilderResult
        {
            ExtractDataTask         extractData          = new ExtractDataTask();
            List <CachedAssetState> carryOverCachedState = new List <CachedAssetState>();
            var tempPath = Path.GetDirectoryName(Application.dataPath) + "/Library/com.unity.addressables/StreamingAssetsCopy/" + PlatformMappingService.GetPlatform() + "/addressables_content_state.bin";

            var playerBuildVersion = builderInput.PlayerVersion;

            if (m_AllBundleInputDefs.Count > 0)
            {
                if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
                {
                    return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "Unsaved scenes"));
                }

                var buildTarget      = builderInput.Target;
                var buildTargetGroup = builderInput.TargetGroup;

                var buildParams = new AddressableAssetsBundleBuildParameters(
                    aaContext.settings,
                    aaContext.bundleToAssetGroup,
                    buildTarget,
                    buildTargetGroup,
                    aaContext.settings.buildSettings.bundleBuildPath);

                var builtinShaderBundleName = aaContext.settings.DefaultGroup.Guid + "_unitybuiltinshaders.bundle";
                var buildTasks = RuntimeDataBuildTasks(builtinShaderBundleName);
                buildTasks.Add(extractData);

                string aaPath = aaContext.settings.AssetPath;
                IBundleBuildResults results;
                using (m_Log.ScopedStep(LogLevel.Info, "ContentPipeline.BuildAssetBundles"))
                {
                    var exitCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(m_AllBundleInputDefs), out results, buildTasks, aaContext, m_Log);

                    if (exitCode < ReturnCode.Success)
                    {
                        return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "SBP Error" + exitCode));
                    }
                }
                if (aaContext.settings == null && !string.IsNullOrEmpty(aaPath))
                {
                    aaContext.settings = AssetDatabase.LoadAssetAtPath <AddressableAssetSettings>(aaPath);
                }

                using (var progressTracker = new UnityEditor.Build.Pipeline.Utilities.ProgressTracker())
                    using (m_Log.ScopedStep(LogLevel.Info, "GenerateLocationListsTask.Run"))
                    {
                        progressTracker.UpdateTask("Generating Addressables Locations");
                        GenerateLocationListsTask.Run(aaContext, extractData.WriteData);
                    }

                var groups = aaContext.settings.groups.Where(g => g != null);

                using (m_Log.ScopedStep(LogLevel.Info, "PostProcessBundles"))
                    using (var progressTracker = new UnityEditor.Build.Pipeline.Utilities.ProgressTracker())
                    {
                        progressTracker.UpdateTask("Post Processing AssetBundles");

                        Dictionary <string, ContentCatalogDataEntry> primaryKeyToCatalogEntry = new Dictionary <string, ContentCatalogDataEntry>();
                        foreach (var loc in aaContext.locations)
                        {
                            if (loc != null && loc.Keys[0] != null && loc.Keys[0] is string && !primaryKeyToCatalogEntry.ContainsKey((string)loc.Keys[0]))
                            {
                                primaryKeyToCatalogEntry[(string)loc.Keys[0]] = loc;
                            }
                        }

                        foreach (var assetGroup in groups)
                        {
                            if (aaContext.assetGroupToBundles.TryGetValue(assetGroup, out List <string> buildBundles))
                            {
                                List <string> outputBundles = new List <string>();
                                for (int i = 0; i < buildBundles.Count; ++i)
                                {
                                    var b = m_AllBundleInputDefs.FindIndex(inputDef =>
                                                                           buildBundles[i].StartsWith(inputDef.assetBundleName));
                                    outputBundles.Add(b >= 0 ? m_OutputAssetBundleNames[b] : buildBundles[i]);
                                }

                                PostProcessBundles(assetGroup, buildBundles, outputBundles, results, extractData.WriteData, aaContext.runtimeData, aaContext.locations, builderInput.Registry, primaryKeyToCatalogEntry);
                            }
                        }
                    }

                ProcessCatalogEntriesForBuild(aaContext, m_Log, groups, builderInput, extractData.WriteData, carryOverCachedState, m_BundleToInternalId);

                foreach (var r in results.WriteResults)
                {
                    m_Linker.AddTypes(r.Value.includedTypes);
                }
            }

            var contentCatalog = new ContentCatalogData(aaContext.locations, ResourceManagerRuntimeData.kCatalogAddress);

            contentCatalog.ResourceProviderData.AddRange(m_ResourceProviderData);
            foreach (var t in aaContext.providerTypes)
            {
                contentCatalog.ResourceProviderData.Add(ObjectInitializationData.CreateSerializedInitializationData(t));
            }

            contentCatalog.InstanceProviderData = ObjectInitializationData.CreateSerializedInitializationData(instanceProviderType.Value);
            contentCatalog.SceneProviderData    = ObjectInitializationData.CreateSerializedInitializationData(sceneProviderType.Value);

            //save catalog
            var jsonText = JsonUtility.ToJson(contentCatalog);

            CreateCatalogFiles(jsonText, builderInput, aaContext);

            foreach (var pd in contentCatalog.ResourceProviderData)
            {
                m_Linker.AddTypes(pd.ObjectType.Value);
                m_Linker.AddTypes(pd.GetRuntimeTypes());
            }
            m_Linker.AddTypes(contentCatalog.InstanceProviderData.ObjectType.Value);
            m_Linker.AddTypes(contentCatalog.InstanceProviderData.GetRuntimeTypes());
            m_Linker.AddTypes(contentCatalog.SceneProviderData.ObjectType.Value);
            m_Linker.AddTypes(contentCatalog.SceneProviderData.GetRuntimeTypes());

            foreach (var io in aaContext.settings.InitializationObjects)
            {
                var provider = io as IObjectInitializationDataProvider;
                if (provider != null)
                {
                    var id = provider.CreateObjectInitializationData();
                    aaContext.runtimeData.InitializationObjects.Add(id);
                    m_Linker.AddTypes(id.ObjectType.Value);
                    m_Linker.AddTypes(id.GetRuntimeTypes());
                }
            }

            m_Linker.AddTypes(typeof(Addressables));
            m_Linker.Save(Addressables.BuildPath + "/link.xml");
            var settingsPath = Addressables.BuildPath + "/" + builderInput.RuntimeSettingsFilename;

            WriteFile(settingsPath, JsonUtility.ToJson(aaContext.runtimeData), builderInput.Registry);

            var opResult = AddressableAssetBuildResult.CreateResult <TResult>(settingsPath, aaContext.locations.Count);
            //save content update data if building for the player
            var allEntries = new List <AddressableAssetEntry>();

            aaContext.settings.GetAllAssets(allEntries, false, g => g != null && g.HasSchema <ContentUpdateGroupSchema>() && g.GetSchema <ContentUpdateGroupSchema>().StaticContent);

            var remoteCatalogLoadPath = aaContext.settings.BuildRemoteCatalog ? aaContext.settings.RemoteCatalogLoadPath.GetValue(aaContext.settings) : string.Empty;

            if (extractData.BuildCache != null && ContentUpdateScript.SaveContentState(aaContext.locations, tempPath, allEntries, extractData.DependencyData, playerBuildVersion, remoteCatalogLoadPath, carryOverCachedState))
            {
                try {
                    var contentStatePath = ContentUpdateScript.GetContentStateDataPath(false);
                    File.Copy(tempPath, contentStatePath, true);
                    builderInput.Registry.AddFile(contentStatePath);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                }
            }

            return(opResult);
        }
Пример #5
0
        TResult DoBuild <TResult>(AddressablesDataBuilderInput builderInput, AddressableAssetSettings aaSettings, AddressableAssetsBuildContext aaContext) where TResult : IDataBuilderResult
        {
            if (m_AllBundleInputDefinitions.Count > 0)
            {
                if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
                {
                    return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "Unsaved scenes"));
                }

                var             buildTarget             = builderInput.Target;
                var             buildTargetGroup        = builderInput.TargetGroup;
                var             buildParams             = new AddressableAssetsBundleBuildParameters(aaSettings, aaContext.bundleToAssetGroup, buildTarget, buildTargetGroup, aaSettings.buildSettings.bundleBuildPath);
                var             builtinShaderBundleName = aaSettings.DefaultGroup.Name.ToLower().Replace(" ", "").Replace('\\', '/').Replace("//", "/") + "_unitybuiltinshaders.bundle";
                var             buildTasks  = RuntimeDataBuildTasks(aaSettings.buildSettings.compileScriptsInVirtualMode, builtinShaderBundleName);
                ExtractDataTask extractData = new ExtractDataTask();
                buildTasks.Add(extractData);

                string aaPath = aaSettings.AssetPath;
                IBundleBuildResults results;
                var exitCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(m_AllBundleInputDefinitions), out results, buildTasks, aaContext);

                if (exitCode < ReturnCode.Success)
                {
                    return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "SBP Error" + exitCode));
                }

                if (aaSettings == null && !string.IsNullOrEmpty(aaPath))
                {
                    aaSettings = AssetDatabase.LoadAssetAtPath <AddressableAssetSettings>(aaPath);
                }
            }

            var bundledAssets = new Dictionary <object, HashSet <string> >();

            foreach (var loc in aaContext.locations)
            {
                if (loc.Dependencies != null && loc.Dependencies.Count > 0)
                {
                    for (int i = 0; i < loc.Dependencies.Count; i++)
                    {
                        var dep = loc.Dependencies[i];
                        HashSet <string> assetsInBundle;
                        if (!bundledAssets.TryGetValue(dep, out assetsInBundle))
                        {
                            bundledAssets.Add(dep, assetsInBundle = new HashSet <string>());
                        }
                        if (i == 0 && !assetsInBundle.Contains(loc.InternalId)) //only add the asset to the first bundle...
                        {
                            assetsInBundle.Add(loc.InternalId);
                        }
                    }
                }
            }

            foreach (var bd in bundledAssets)
            {
                AddressableAssetGroup group = aaSettings.DefaultGroup;
                string groupGuid;
                if (aaContext.bundleToAssetGroup.TryGetValue(bd.Key as string, out groupGuid))
                {
                    group = aaSettings.FindGroup(g => g.Guid == groupGuid);
                }

                var schema = group.GetSchema <BundledAssetGroupSchema>();
                if (schema != null)
                {
                    var  bundleLocData = aaContext.locations.First(s => s.Keys[0] == bd.Key);
                    var  isLocalBundle = IsInternalIdLocal(bundleLocData.InternalId);
                    uint crc           = (uint)UnityEngine.Random.Range(0, int.MaxValue);
                    var  hash          = Guid.NewGuid().ToString();

                    string originalBundleName = bd.Key as string;
                    string newBundleName      = BuildUtility.GetNameWithHashNaming(schema.BundleNaming, hash, originalBundleName);
                    bundleLocData.InternalId = bundleLocData.InternalId.Remove(bundleLocData.InternalId.Length - originalBundleName.Length) + newBundleName;

                    var virtualBundleName = AddressablesRuntimeProperties.EvaluateString(bundleLocData.InternalId);
                    var bundleData        = new VirtualAssetBundle(virtualBundleName, isLocalBundle, crc, hash);

                    long dataSize   = 0;
                    long headerSize = 0;
                    foreach (var a in bd.Value)
                    {
                        var size = ComputeSize(a);
                        bundleData.Assets.Add(new VirtualAssetBundleEntry(a, size));
                        dataSize   += size;
                        headerSize += a.Length * 5; //assume 5x path length overhead size per item, probably much less
                    }
                    if (bd.Value.Count == 0)
                    {
                        dataSize   = 100 * 1024;
                        headerSize = 1024;
                    }
                    bundleData.SetSize(dataSize, headerSize);


                    var requestOptions = new VirtualAssetBundleRequestOptions
                    {
                        Crc             = schema.UseAssetBundleCrc ? crc : 0,
                        Hash            = schema.UseAssetBundleCache ? hash : "",
                        ChunkedTransfer = schema.ChunkedTransfer,
                        RedirectLimit   = schema.RedirectLimit,
                        RetryCount      = schema.RetryCount,
                        Timeout         = schema.Timeout,
                        BundleName      = Path.GetFileName(bundleLocData.InternalId),
                        BundleSize      = dataSize + headerSize
                    };
                    bundleLocData.Data = requestOptions;

                    var bundleProviderId         = schema.GetBundleCachedProviderId();
                    var virtualBundleRuntimeData = m_CreatedProviderIds[bundleProviderId];
                    virtualBundleRuntimeData.AssetBundles.Add(bundleData);
                }
            }
            foreach (var kvp in m_CreatedProviderIds)
            {
                if (kvp.Value != null)
                {
                    var bundleProviderData = ObjectInitializationData.CreateSerializedInitializationData <VirtualAssetBundleProvider>(kvp.Key, kvp.Value);
                    m_ResourceProviderData.Add(bundleProviderData);
                }
            }

            var contentCatalog = new ContentCatalogData(aaContext.locations, ResourceManagerRuntimeData.kCatalogAddress);

            contentCatalog.ResourceProviderData.AddRange(m_ResourceProviderData);
            foreach (var t in aaContext.providerTypes)
            {
                contentCatalog.ResourceProviderData.Add(ObjectInitializationData.CreateSerializedInitializationData(t));
            }

            contentCatalog.InstanceProviderData = ObjectInitializationData.CreateSerializedInitializationData(instanceProviderType.Value);
            contentCatalog.SceneProviderData    = ObjectInitializationData.CreateSerializedInitializationData(sceneProviderType.Value);
            //save catalog
            WriteFile(string.Format(m_PathFormat, "", "catalog"), JsonUtility.ToJson(contentCatalog), builderInput.Registry);


            foreach (var io in aaSettings.InitializationObjects)
            {
                if (io is IObjectInitializationDataProvider)
                {
                    aaContext.runtimeData.InitializationObjects.Add((io as IObjectInitializationDataProvider).CreateObjectInitializationData());
                }
            }

            var settingsPath = string.Format(m_PathFormat, "", "settings");

            WriteFile(settingsPath, JsonUtility.ToJson(aaContext.runtimeData), builderInput.Registry);

            //inform runtime of the init data path
            var runtimeSettingsPath = string.Format(m_PathFormat, "file://{UnityEngine.Application.dataPath}/../", "settings");

            PlayerPrefs.SetString(Addressables.kAddressablesRuntimeDataPath, runtimeSettingsPath);
            var result = AddressableAssetBuildResult.CreateResult <TResult>(settingsPath, aaContext.locations.Count);

            return(result);
        }
Пример #6
0
        /// <summary>
        /// The method that does the actual building after all the groups have been processed.
        /// </summary>
        /// <param name="builderInput">The generic builderInput of the</param>
        /// <param name="aaContext"></param>
        /// <typeparam name="TResult"></typeparam>
        /// <returns></returns>
        protected virtual TResult DoBuild <TResult>(AddressablesDataBuilderInput builderInput, AddressableAssetsBuildContext aaContext) where TResult : IDataBuilderResult
        {
            ExtractDataTask extractData = new ExtractDataTask();
            var             tempPath    = Path.GetDirectoryName(Application.dataPath) + "/Library/com.unity.addressables/StreamingAssetsCopy/" + PlatformMappingService.GetPlatform() + "/addressables_content_state.bin";

            var playerBuildVersion = builderInput.PlayerVersion;

            if (m_AllBundleInputDefs.Count > 0)
            {
                if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
                {
                    return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "Unsaved scenes"));
                }

                var buildTarget      = builderInput.Target;
                var buildTargetGroup = builderInput.TargetGroup;

                var buildParams = new AddressableAssetsBundleBuildParameters(
                    aaContext.settings,
                    aaContext.bundleToAssetGroup,
                    buildTarget,
                    buildTargetGroup,
                    aaContext.settings.buildSettings.bundleBuildPath);

                var builtinShaderBundleName = aaContext.settings.DefaultGroup.Name.ToLower().Replace(" ", "").Replace('\\', '/').Replace("//", "/") + "_unitybuiltinshaders.bundle";
                var buildTasks = RuntimeDataBuildTasks(builtinShaderBundleName);
                buildTasks.Add(extractData);

                string aaPath = aaContext.settings.AssetPath;
                IBundleBuildResults results;
                var exitCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(m_AllBundleInputDefs), out results, buildTasks, aaContext);

                if (exitCode < ReturnCode.Success)
                {
                    return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "SBP Error" + exitCode));
                }
                if (aaContext.settings == null && !string.IsNullOrEmpty(aaPath))
                {
                    aaContext.settings = AssetDatabase.LoadAssetAtPath <AddressableAssetSettings>(aaPath);
                }

                GenerateLocationListsTask.Run(aaContext, extractData.WriteData);

                foreach (var assetGroup in aaContext.settings.groups)
                {
                    List <string> bundles;
                    if (aaContext.assetGroupToBundles.TryGetValue(assetGroup, out bundles))
                    {
                        PostProcessBundles(assetGroup, bundles, results, extractData.WriteData, aaContext.runtimeData, aaContext.locations, builderInput.Registry);
                        PostProcessCatalogEnteries(assetGroup, extractData.WriteData, aaContext.locations, builderInput.Registry);
                    }
                }
                foreach (var r in results.WriteResults)
                {
                    m_Linker.AddTypes(r.Value.includedTypes);
                }
            }

            //save catalog
            var contentCatalog = new ContentCatalogData(aaContext.locations);

            contentCatalog.ResourceProviderData.AddRange(m_ResourceProviderData);
            foreach (var t in aaContext.providerTypes)
            {
                contentCatalog.ResourceProviderData.Add(ObjectInitializationData.CreateSerializedInitializationData(t));
            }

            contentCatalog.InstanceProviderData = ObjectInitializationData.CreateSerializedInitializationData(instanceProviderType.Value);
            contentCatalog.SceneProviderData    = ObjectInitializationData.CreateSerializedInitializationData(sceneProviderType.Value);
            CreateCatalog(aaContext.settings, contentCatalog, aaContext.runtimeData.CatalogLocations, playerBuildVersion, builderInput.RuntimeCatalogFilename, builderInput.Registry);
            foreach (var pd in contentCatalog.ResourceProviderData)
            {
                m_Linker.AddTypes(pd.ObjectType.Value);
                m_Linker.AddTypes(pd.GetRuntimeTypes());
            }
            m_Linker.AddTypes(contentCatalog.InstanceProviderData.ObjectType.Value);
            m_Linker.AddTypes(contentCatalog.InstanceProviderData.GetRuntimeTypes());
            m_Linker.AddTypes(contentCatalog.SceneProviderData.ObjectType.Value);
            m_Linker.AddTypes(contentCatalog.SceneProviderData.GetRuntimeTypes());

            foreach (var io in aaContext.settings.InitializationObjects)
            {
                var provider = io as IObjectInitializationDataProvider;
                if (provider != null)
                {
                    var id = provider.CreateObjectInitializationData();
                    aaContext.runtimeData.InitializationObjects.Add(id);
                    m_Linker.AddTypes(id.ObjectType.Value);
                    m_Linker.AddTypes(id.GetRuntimeTypes());
                }
            }
            m_Linker.AddTypes(typeof(Addressables));
            m_Linker.Save(Addressables.BuildPath + "/link.xml");
            var settingsPath = Addressables.BuildPath + "/" + builderInput.RuntimeSettingsFilename;

            WriteFile(settingsPath, JsonUtility.ToJson(aaContext.runtimeData), builderInput.Registry);

            var opResult = AddressableAssetBuildResult.CreateResult <TResult>(settingsPath, aaContext.locations.Count);
            //save content update data if building for the player
            var allEntries = new List <AddressableAssetEntry>();

            aaContext.settings.GetAllAssets(allEntries, false, g => g.HasSchema <ContentUpdateGroupSchema>() && g.GetSchema <ContentUpdateGroupSchema>().StaticContent);

            var remoteCatalogLoadPath = aaContext.settings.BuildRemoteCatalog ? aaContext.settings.RemoteCatalogLoadPath.GetValue(aaContext.settings) : string.Empty;

            if (extractData.BuildCache != null && ContentUpdateScript.SaveContentState(aaContext.locations, tempPath, allEntries, extractData.DependencyData, playerBuildVersion, remoteCatalogLoadPath))
            {
                try
                {
                    File.Copy(tempPath, ContentUpdateScript.GetContentStateDataPath(false), true);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                }
            }

            return(opResult);
        }
Пример #7
0
        public static void BuildAll()
        {
            Clear();
            var Mods   = ModsEditor.GetMods();
            int length = Mods.Length;

            for (int i = 0; i < length; i++)
            {
                var ModInfo         = ModsEditor.GetModInfo(Mods[i]);
                var ModOutPutFolder = OutPutFolder + "/" + ModInfo.PackageName;
                //Windows64版本构建
                //构建参数
                var param = new BundleBuildParameters(BuildTarget.StandaloneWindows64, BuildTargetGroup.Standalone, ModOutPutFolder);
                param.BundleCompression = BuildCompression.LZ4;
                //填入资源
                var content = new BundleBuildContent(new AssetBundleBuild[] { GetAllAssets(ModInfo, "winmod") });
                IBundleBuildResults results;
                //构建包
                ReturnCode code = ContentPipeline.BuildAssetBundles(param, content, out results);
                if (code != ReturnCode.Success)
                {
                    if (code == ReturnCode.Canceled)
                    {
                        return;//如果取消,直接返回
                    }
                    Debug.LogError("构建失败!错误原因:" + code.ToString());
                }

                //OSX版本构建
                //构建参数
                param.Target = BuildTarget.StandaloneOSX;
                //填入资源
                content = new BundleBuildContent(new AssetBundleBuild[] { GetAllAssets(ModInfo, "osxmod") });
                results = null;
                //构建包
                code = ContentPipeline.BuildAssetBundles(param, content, out results);
                if (code != ReturnCode.Success)
                {
                    if (code == ReturnCode.Canceled)
                    {
                        return;//如果取消,直接返回
                    }
                    Debug.LogError("构建失败!错误原因:" + code.ToString());
                }

                //Linux版本构建
                //构建参数
                param.Target = BuildTarget.StandaloneLinux64;
                //填入资源
                content = new BundleBuildContent(new AssetBundleBuild[] { GetAllAssets(ModInfo, "linuxmod") });
                results = null;
                //构建包
                code = ContentPipeline.BuildAssetBundles(param, content, out results);
                if (code != ReturnCode.Success)
                {
                    if (code == ReturnCode.Canceled)
                    {
                        return;//如果取消,直接返回
                    }
                    Debug.LogError("构建失败!错误原因:" + code.ToString());
                }

                //Android版本构建
                //构建参数
                param.Target = BuildTarget.Android;
                param.Group  = BuildTargetGroup.Android;
                //填入资源
                content = new BundleBuildContent(new AssetBundleBuild[] { GetAllAssets(ModInfo, "androidmod") });
                results = null;
                //构建包
                code = ContentPipeline.BuildAssetBundles(param, content, out results);
                if (code != ReturnCode.Success)
                {
                    if (code == ReturnCode.Canceled)
                    {
                        return;//如果取消,直接返回
                    }
                    Debug.LogError("构建失败!错误原因:" + code.ToString());
                }

                //ios版本构建
                //构建参数
                param.Target = BuildTarget.iOS;
                param.Group  = BuildTargetGroup.iOS;
                //填入资源
                content = new BundleBuildContent(new AssetBundleBuild[] { GetAllAssets(ModInfo, "iosmod") });
                results = null;
                //构建包
                code = ContentPipeline.BuildAssetBundles(param, content, out results);
                if (code != ReturnCode.Success)
                {
                    if (code == ReturnCode.Canceled)
                    {
                        return;//如果取消,直接返回
                    }
                    Debug.LogError("构建失败!错误原因:" + code.ToString());
                }

                //生成ModInfo文件
                ModInfo = ModsEditor.GetModInfo(Mods[i]);//由于构建后资源会被释放,这里需要重载
                using (FileStream fs = File.Create(ModOutPutFolder + "/" + ModInfo.PackageName + ".json"))
                {
                    StreamWriter sw = new StreamWriter(fs);
                    sw.Write(JsonConvert.SerializeObject(ModInfo));
                    sw.Dispose();
                }
            }
        }
Пример #8
0
        public static void BuildAssetBundles(AssetbundleBuildSettings settings, BuildType buildType)
        {
            var bundleList = new List <AssetBundleBuild>();

            foreach (var setting in settings.BundleSettings)
            {
                var folderPath = AssetDatabase.GUIDToAssetPath(setting.Folder.guid);
                var dir        = new DirectoryInfo(Path.Combine(Application.dataPath, folderPath.Remove(0, 7)));
                if (!dir.Exists)
                {
                    throw new Exception($"Could not found Path {folderPath} for {setting.BundleName}");
                }
                var assetPathes = new List <string>();
                var loadPathes  = new List <string>();
                AssetbundleBuildSettings.GetFilesInDirectory(string.Empty, assetPathes, loadPathes, dir, setting.IncludeSubfolder);
                if (assetPathes.Count == 0)
                {
                    Debug.LogWarning($"Could not found Any Assets {folderPath} for {setting.BundleName}");
                }
                var newBundle = new AssetBundleBuild();
                newBundle.assetBundleName  = setting.BundleName;
                newBundle.assetNames       = assetPathes.ToArray();
                newBundle.addressableNames = loadPathes.ToArray();
                bundleList.Add(newBundle);
            }

            var buildTarget = EditorUserBuildSettings.activeBuildTarget;
            var groupTarget = BuildPipeline.GetBuildTargetGroup(buildTarget);

            var outputPath  = Path.Combine(buildType == BuildType.Local ? settings.LocalOutputPath : settings.RemoteOutputPath, buildTarget.ToString());
            var buildParams = new CustomBuildParameters(settings, buildTarget, groupTarget, outputPath, buildType == BuildType.Local);

            buildParams.UseCache = !settings.ForceRebuild;

            if (buildParams.UseCache && settings.UseCacheServer)
            {
                buildParams.CacheServerHost = settings.CacheServerHost;
                buildParams.CacheServerPort = settings.CacheServerPort;
            }

            s_CurrentBuildingSettings = settings;
            s_CurrentBuildType        = buildType;
            ContentPipeline.BuildCallbacks.PostPackingCallback += PostPackingForSelectiveBuild;
            var returnCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(bundleList.ToArray()), out var results);

            ContentPipeline.BuildCallbacks.PostPackingCallback -= PostPackingForSelectiveBuild;

            if (buildType == BuildType.Dry)
            {
                EditorUtility.DisplayDialog("Build Succeeded!", "Dry bundle build succeeded!", "Confirm");
                return;
            }

            if (returnCode == ReturnCode.Success)
            {
                WriteManifestFile(outputPath, results, buildTarget, settings.RemoteURL);
                WriteLogFile(outputPath, results);
                //only remote bundle build generates link.xml

                switch (buildType)
                {
                case BuildType.Local:
                    EditorUtility.DisplayDialog("Build Succeeded!", "Local bundle build succeeded!", "Confirm");
                    break;

                case BuildType.Remote:
                    var linkPath = TypeLinkerGenerator.Generate(settings, results);
                    EditorUtility.DisplayDialog("Build Succeeded!", $"Remote bundle build succeeded, \n {linkPath} updated!", "Confirm");
                    break;

                case BuildType.Dry:
                    EditorUtility.DisplayDialog("Build Succeeded!", $"Dry bundle build succeeded", "Confirm");
                    break;
                }
            }
            else
            {
                EditorUtility.DisplayDialog("Build Failed!", $"Bundle build failed, \n Code : {returnCode}", "Confirm");
                Debug.LogError(returnCode);
            }
        }
Пример #9
0
        internal void BuildGroup(ABGroup group)
        {
            if (Settings == null)
            {
                throw new FileNotFoundException("Setttings not found", "ABSettings.asset");
            }
            if (group == null)
            {
                throw new NullReferenceException("SimpleGroupAssetBundles is null");
            }
            string           buildPath        = string.Empty;
            string           localLoadPath    = string.Empty;
            string           remoteLoadPath   = string.Empty;
            BuildTarget      buildTarget      = BuildTarget.StandaloneWindows;
            BuildTargetGroup buildTargetGroup = BuildTargetGroup.Standalone;

            if (group.IsCustomSettings)
            {
                buildPath        = group.BuildPath;
                localLoadPath    = group.LocalLoadPath;
                remoteLoadPath   = group.RemoteLoadPath;
                buildTarget      = group.BuildTarget;
                buildTargetGroup = group.BuildTargetGroup;
            }
            else
            {
                buildPath        = $"{Settings.BuildPath}/{group.BuildPath}";
                localLoadPath    = $"{Settings.LocalLoadPath}/{group.LocalLoadPath}";
                remoteLoadPath   = $"{Settings.RemoteLoadPath}/{group.RemoteLoadPath}";
                buildTarget      = Settings.BuildTarget;
                buildTargetGroup = Settings.BuildTargetGroup;
            }
            if (buildPath.IndexOfAny(Path.GetInvalidPathChars()) != -1)
            {
                throw new DirectoryNotFoundException("BuildPath invalid chars");
            }
            if (localLoadPath.IndexOfAny(Path.GetInvalidPathChars()) != -1)
            {
                throw new DirectoryNotFoundException("LocalLoadPath invalid chars");
            }
            if (remoteLoadPath.IndexOfAny(Path.GetInvalidPathChars()) != -1)
            {
                throw new DirectoryNotFoundException("LocalLoadPath invalid chars");
            }
            if (group.BundleBuilds == null || group.BundleBuilds.Count() <= 0)
            {
                Debug.LogWarning($"Бандлы для билда группы {group.Name} являются null или их нет. Билд этой группы не будет производиться");
                return;
            }
            if (!Directory.Exists(buildPath))
            {
                try
                {
                    Directory.CreateDirectory(buildPath);
                }
                catch (IOException ex)
                {
                    throw ex;
                    throw new IOException("Путь билда указывает на файл");
                }
                catch (NotSupportedException ex)
                {
                    throw ex;
                    throw new NotSupportedException("Путь билда содержит двоеточие (:), которое не является частью метки");
                }
            }
            _currentManifest                = new ABManifest();
            _currentManifest.Name           = group.Name;
            _currentManifest.Version        = group.Version;
            _currentManifest.LocalLoadPath  = localLoadPath;
            _currentManifest.RemoteLoadPath = remoteLoadPath;
            foreach (var item in group.BundleBuilds)
            {
                _currentManifest.Bundles.Add(new BundleInfo {
                    Name = item.assetBundleName
                });
            }
            var parameters = new BundleBuildParameters(buildTarget, buildTargetGroup, buildPath);

            parameters.BundleCompression = group.Compression;
            var buildContent = new BundleBuildContent(group.BundleBuilds);

            foreach (var item in buildContent.Assets)
            {
                _currentManifest.Assets.Add(new AssetInfo()
                {
                    Name = buildContent.Addresses[item],
                    Path = AssetDatabase.GUIDToAssetPath(item.ToString())
                });
            }
            foreach (var item in buildContent.Scenes)
            {
                _currentManifest.Scenes.Add(new AssetInfo()
                {
                    Name = buildContent.Addresses[item],
                    Path = AssetDatabase.GUIDToAssetPath(item.ToString())
                });
            }
            IBundleBuildResults results;
            var returnCode = ContentPipeline.BuildAssetBundles(parameters, buildContent, out results, new[] { new ArchiveAndCompressBundles() });

            if (returnCode == ReturnCode.Success)
            {
                string jsonContent = JsonUtility.ToJson(_currentManifest);
                using (var sw = File.CreateText(Path.Combine(buildPath, $"manifest-{group.Name}.json")))
                {
                    sw.Write(jsonContent);
                }
            }
        }
        List <AnalyzeResult> DoFakeBuild(AddressableAssetSettings settings)
        {
            m_ImplicitAssets = new HashSet <GUID>();
            List <AnalyzeResult> emptyResult = new List <AnalyzeResult>();

            emptyResult.Add(new AnalyzeResult(ruleName + " - No issues found"));
            var context = new AddressablesDataBuilderInput(settings);
            var timer   = new Stopwatch();

            timer.Start();
            var aaSettings = context.AddressableSettings;

            //gather entries
            var locations          = new List <ContentCatalogDataEntry>();
            var allBundleInputDefs = new List <AssetBundleBuild>();
            var bundleToAssetGroup = new Dictionary <string, string>();
            var runtimeData        = new ResourceManagerRuntimeData();

            runtimeData.LogResourceManagerExceptions = aaSettings.buildSettings.LogResourceManagerExceptions;

            foreach (var assetGroup in aaSettings.groups)
            {
                var schema = assetGroup.GetSchema <BundledAssetGroupSchema>();
                if (schema == null)
                {
                    continue;
                }

                var bundleInputDefs = new List <AssetBundleBuild>();
                BuildScriptPackedMode.PrepGroupBundlePacking(assetGroup, bundleInputDefs, locations, schema.BundleMode);
                for (int i = 0; i < bundleInputDefs.Count; i++)
                {
                    if (bundleToAssetGroup.ContainsKey(bundleInputDefs[i].assetBundleName))
                    {
                        var bid     = bundleInputDefs[i];
                        int count   = 1;
                        var newName = bid.assetBundleName;
                        while (bundleToAssetGroup.ContainsKey(newName) && count < 1000)
                        {
                            newName = bid.assetBundleName.Replace(".bundle", string.Format("{0}.bundle", count++));
                        }
                        bundleInputDefs[i] = new AssetBundleBuild {
                            assetBundleName = newName, addressableNames = bid.addressableNames, assetBundleVariant = bid.assetBundleVariant, assetNames = bid.assetNames
                        };
                    }

                    bundleToAssetGroup.Add(bundleInputDefs[i].assetBundleName, assetGroup.Guid);
                }
                allBundleInputDefs.AddRange(bundleInputDefs);
            }
            ExtractDataTask extractData = new ExtractDataTask();

            if (allBundleInputDefs.Count > 0)
            {
                if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
                {
                    Debug.LogError("Cannot run Analyze with unsaved scenes");
                    return(emptyResult);
                }

                var buildTarget             = context.Target;
                var buildTargetGroup        = context.TargetGroup;
                var buildParams             = new AddressableAssetsBundleBuildParameters(aaSettings, bundleToAssetGroup, buildTarget, buildTargetGroup, aaSettings.buildSettings.bundleBuildPath);
                var builtinShaderBundleName = aaSettings.DefaultGroup.Name.ToLower().Replace(" ", "").Replace('\\', '/').Replace("//", "/") + "_unitybuiltinshaders.bundle";
                var buildTasks = RuntimeDataBuildTasks(builtinShaderBundleName);
                buildTasks.Add(extractData);

                var aaContext = new AddressableAssetsBuildContext
                {
                    settings           = aaSettings,
                    runtimeData        = runtimeData,
                    bundleToAssetGroup = bundleToAssetGroup,
                    locations          = locations
                };

                IBundleBuildResults buildResults;
                var exitCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(allBundleInputDefs), out buildResults, buildTasks, aaContext);
                GenerateLocationListsTask.Run(aaContext, extractData.WriteData);
                if (exitCode < ReturnCode.Success)
                {
                    Debug.LogError("Analyze build failed. " + exitCode);
                    return(emptyResult);
                }

                HashSet <GUID> explicitGuids = new HashSet <GUID>();
                foreach (var atf in extractData.WriteData.AssetToFiles)
                {
                    explicitGuids.Add(atf.Key);
                }

                Dictionary <GUID, List <string> > implicitGuids = new Dictionary <GUID, List <string> >();
                foreach (var fto in extractData.WriteData.FileToObjects)
                {
                    foreach (ObjectIdentifier g in fto.Value)
                    {
                        if (!explicitGuids.Contains(g.guid))
                        {
                            if (!implicitGuids.ContainsKey(g.guid))
                            {
                                implicitGuids.Add(g.guid, new List <string>());
                            }
                            implicitGuids[g.guid].Add(fto.Key);
                        }
                    }
                }

                //dictionary<group, dictionary<bundle, implicit assets >>
                Dictionary <string, Dictionary <string, List <string> > > allIssues = new Dictionary <string, Dictionary <string, List <string> > >();
                foreach (var g in implicitGuids)
                {
                    if (g.Value.Count > 1) //it's duplicated...
                    {
                        var path = AssetDatabase.GUIDToAssetPath(g.Key.ToString());
                        if (!AddressableAssetUtility.IsPathValidForEntry(path) ||
                            path.ToLower().Contains("/resources/") ||
                            path.ToLower().StartsWith("resources/"))
                        {
                            continue;
                        }

                        foreach (var file in g.Value)
                        {
                            var    bun = extractData.WriteData.FileToBundle[file];
                            string groupGuid;
                            if (aaContext.bundleToAssetGroup.TryGetValue(bun, out groupGuid))
                            {
                                var group = aaSettings.FindGroup(grp => grp.Guid == groupGuid);
                                if (group != null)
                                {
                                    Dictionary <string, List <string> > groupData;
                                    if (!allIssues.TryGetValue(group.Name, out groupData))
                                    {
                                        groupData = new Dictionary <string, List <string> >();
                                        allIssues.Add(group.Name, groupData);
                                    }

                                    List <string> assets;
                                    if (!groupData.TryGetValue(bun, out assets))
                                    {
                                        assets = new List <string>();
                                        groupData.Add(bun, assets);
                                    }
                                    assets.Add(path);

                                    m_ImplicitAssets.Add(g.Key);
                                }
                            }
                        }
                    }
                }

                List <AnalyzeResult> result = new List <AnalyzeResult>();
                foreach (var group in allIssues)
                {
                    foreach (var bundle in group.Value)
                    {
                        foreach (var item in bundle.Value)
                        {
                            var issueName = ruleName + kDelimiter + group.Key + kDelimiter + bundle.Key + kDelimiter + item;
                            result.Add(new AnalyzeResult(issueName, MessageType.Warning));
                        }
                    }
                }

                if (result.Count > 0)
                {
                    return(result);
                }
            }
            return(emptyResult);
        }