/// <summary>
        /// Package the specified AssetBundle files, which vary only by <see cref="TextureCompressionFormat"/>, in an
        /// <see cref="AssetPack"/> with the specified delivery mode.
        /// </summary>
        /// <param name="compressionFormatToAssetBundleFilePath">
        /// A dictionary from <see cref="TextureCompressionFormat"/> to AssetBundle files.</param>
        /// <param name="deliveryMode">The <see cref="AssetPackDeliveryMode"/> for the asset pack.</param>
        /// <exception cref="ArgumentException">If the dictionary or asset pack name is invalid.</exception>
        /// <exception cref="FileNotFoundException">If any AssetBundle file doesn't exist.</exception>
        public void AddAssetBundles(
            IDictionary <TextureCompressionFormat, string> compressionFormatToAssetBundleFilePath,
            AssetPackDeliveryMode deliveryMode)
        {
            if (compressionFormatToAssetBundleFilePath.Count == 0)
            {
                throw new ArgumentException("Dictionary should contain at least one AssetBundle");
            }

            if (compressionFormatToAssetBundleFilePath.All(kvp => kvp.Key != TextureCompressionFormat.Default))
            {
                throw new ArgumentException("Dictionary should contain at least one Default compression AssetBundle");
            }

            var assetPackName = GetAssetPackName(compressionFormatToAssetBundleFilePath.Values.First());

            if (compressionFormatToAssetBundleFilePath.Any(kvp => assetPackName != GetAssetPackName(kvp.Value)))
            {
                throw new ArgumentException("All AssetBundles in the Dictionary must have the same name");
            }

            AssetPacks[assetPackName] = new AssetPack
            {
                DeliveryMode = deliveryMode,
                CompressionFormatToAssetBundleFilePath =
                    new Dictionary <TextureCompressionFormat, string>(compressionFormatToAssetBundleFilePath)
            };
        }
        private string CreateAssetPackWithManifest(
            DirectoryInfo rootDirectory, string assetPackName, AssetPackDeliveryMode deliveryMode)
        {
            var androidManifestFilePath    = Path.Combine(rootDirectory.FullName, AndroidManifestFileName);
            var assetPackManifestXDocument = CreateAssetPackManifestXDocument(assetPackName, deliveryMode);

            assetPackManifestXDocument.Save(androidManifestFilePath);

            var source           = rootDirectory.CreateSubdirectory("manifest");
            var aaptErrorMessage = _androidAssetPackagingTool.Link(androidManifestFilePath, source.FullName);

            if (aaptErrorMessage != null)
            {
                return(DisplayBuildError("AAPT2 link " + assetPackName, aaptErrorMessage));
            }

            // aapt2 link creates an empty resource table even though asset packs have no resources.
            // Bundletool fails if the asset pack has a resources.pb. Only retain the AndroidManifest.xml file.
            var destination = GetDestinationSubdirectory(rootDirectory);

            foreach (var sourceFileInfo in source.GetFiles())
            {
                if (sourceFileInfo.Name == AndroidManifestFileName)
                {
                    var destinationSubdirectory = destination.CreateSubdirectory(ManifestDirectoryName);
                    sourceFileInfo.MoveTo(Path.Combine(destinationSubdirectory.FullName, sourceFileInfo.Name));
                }
            }

            return(null);
        }
        /// <summary>
        /// Package the specified AssetBundle file in its own <see cref="AssetPack"/> with the specified delivery mode.
        /// The name of the created asset pack will match that of the specified AssetBundle file.
        /// </summary>
        /// <param name="assetBundleFilePath">The path to a single AssetBundle file.</param>
        /// <param name="deliveryMode">The <see cref="AssetPackDeliveryMode"/> for the asset pack.</param>
        /// <exception cref="ArgumentException">If the asset pack name is invalid.</exception>
        /// <exception cref="FileNotFoundException">If the AssetBundle file doesn't exist.</exception>
        public void AddAssetBundle(string assetBundleFilePath, AssetPackDeliveryMode deliveryMode)
        {
            var assetPackName = GetAssetPackName(assetBundleFilePath);

            AssetPacks[assetPackName] = new AssetPack
            {
                DeliveryMode        = deliveryMode,
                AssetBundleFilePath = assetBundleFilePath
            };
        }
        /// <summary>
        /// Package all raw assets in the specified folder in an <see cref="AssetPack"/> with the specified name and
        /// using the specified delivery mode.
        /// </summary>
        /// <param name="assetPackName">The name of the asset pack.</param>
        /// <param name="assetsFolderPath">
        /// The path to a directory whose files will be directly copied into the asset pack during app bundle creation.
        /// </param>
        /// <param name="deliveryMode">The <see cref="AssetPackDeliveryMode"/> for the asset pack.</param>
        /// <exception cref="ArgumentException">If the <see cref="assetPackName"/> is invalid.</exception>
        /// <exception cref="FileNotFoundException">If the <see cref="assetsFolderPath"/> doesn't exist.</exception>
        public void AddAssetsFolder(string assetPackName, string assetsFolderPath, AssetPackDeliveryMode deliveryMode)
        {
            var directoryInfo = new DirectoryInfo(assetsFolderPath);

            if (!directoryInfo.Exists)
            {
                throw new FileNotFoundException("Asset pack directory doesn't exist", assetsFolderPath);
            }

            CheckAssetPackName(assetPackName);
            AssetPacks[assetPackName] = new AssetPack
            {
                DeliveryMode           = deliveryMode,
                AssetPackDirectoryPath = assetsFolderPath
            };
        }
Exemple #5
0
        /// <summary>
        /// Run one or more AssetBundle builds with the specified texture compression formats.
        /// Notes about the <see cref="outputPath"/> parameter:
        /// - If a relative path is provided, the file paths in the returned AssetPackConfig will be relative paths.
        /// - If an absolute path is provided, the file paths in the returned object will be absolute paths.
        /// - AssetBundle builds for additional texture formats will be created in siblings of this directory. For
        ///   example, for outputDirectory "a/b/c" and texture format ASTC, there will be a directory "a/b/c#tcf_astc".
        /// - This directory and any sibling directories must be empty or not exist, otherwise an exception is thrown.
        /// </summary>
        /// <param name="outputPath">The output directory for the ETC1 AssetBundles. See other notes above.</param>
        /// <param name="builds">The main argument to <see cref="BuildPipeline"/>.</param>
        /// <param name="deliveryMode">A delivery mode to apply to every asset pack in the generated config.</param>
        /// <param name="additionalTextureFormats">Texture formats to build for in addition to ETC1.</param>
        /// <param name="assetBundleOptions">Options to pass to <see cref="BuildPipeline"/>.</param>
        /// <returns>An <see cref="AssetPackConfig"/> containing file paths to all generated AssetBundles.</returns>
        public static AssetPackConfig BuildAssetBundles(
            string outputPath,
            AssetBundleBuild[] builds,
            AssetPackDeliveryMode deliveryMode,
            IEnumerable <MobileTextureSubtarget> additionalTextureFormats = null,
            BuildAssetBundleOptions assetBundleOptions = BuildAssetBundleOptions.UncompressedAssetBundle)
        {
            var nameToTextureFormatToPath = BuildAssetBundles(
                outputPath, builds, assetBundleOptions, MobileTextureSubtarget.ETC, additionalTextureFormats);
            var assetPackConfig = new AssetPackConfig();

            foreach (var compressionToPath in nameToTextureFormatToPath.Values)
            {
                assetPackConfig.AddAssetBundles(compressionToPath, deliveryMode);
            }

            return(assetPackConfig);
        }
        /// <summary>
        /// Creates a new XDocument representing the AndroidManifest.xml for an asset pack.
        /// </summary>
        /// <param name="packageName">Package name of this application.</param>
        /// <param name="assetPackName">The name of the asset pack.</param>
        /// <param name="deliveryMode">The <see cref="AssetPackDeliveryMode"/> of this asset pack.</param>
        public static XDocument CreateAssetPackManifestXDocument(
            string packageName, string assetPackName, AssetPackDeliveryMode deliveryMode)
        {
            // TODO: Add support for <dist:instant-delivery>
            var   deliveryTypeXName = ManifestConstants.DistDeliveryXName;
            XName deliveryModeXName;

            switch (deliveryMode)
            {
            case AssetPackDeliveryMode.OnDemand:
                deliveryModeXName = ManifestConstants.DistOnDemandXName;
                break;

            case AssetPackDeliveryMode.InstallTime:
                deliveryModeXName = ManifestConstants.DistInstallTimeName;
                break;

            case AssetPackDeliveryMode.FastFollow:
                deliveryModeXName = ManifestConstants.DistFastFollowName;
                break;

            default:
                throw new ArgumentException("Unexpected delivery mode: " + deliveryMode, "deliveryMode");
            }

            var moduleElement = new XElement(
                ManifestConstants.DistModuleXName,
                new XAttribute(ManifestConstants.DistTypeXName, ManifestConstants.AssetPack),
                new XElement(deliveryTypeXName,
                             new XElement(deliveryModeXName)),
                new XElement(ManifestConstants.DistFusingXName,
                             new XAttribute(ManifestConstants.DistIncludeXName, ManifestConstants.ValueTrue))
                );

            return(new XDocument(new XElement(
                                     ManifestConstants.Manifest,
                                     new XAttribute(ManifestConstants.AndroidXmlns, XNamespace.Get(ManifestConstants.AndroidNamespaceUrl)),
                                     new XAttribute(ManifestConstants.DistXmlns, XNamespace.Get(ManifestConstants.DistNamespaceUrl)),
                                     new XAttribute(ManifestConstants.Package, packageName),
                                     new XAttribute(ManifestConstants.Split, assetPackName),
                                     moduleElement)));
        }
Exemple #7
0
        /// <inheritdoc/>
        public override void OnGUIMultiple(List <AddressableAssetGroupSchema> otherSchemas)
        {
            var so   = new SerializedObject(this);
            var prop = so.FindProperty("m_DeliveryMode");

            // Type/Static Content
            ShowMixedValue(prop, otherSchemas, typeof(bool), "m_DeliveryMode");
            EditorGUI.BeginChangeCheck();
            m_DeliveryMode = (AssetPackDeliveryMode)EditorGUILayout.EnumPopup("Delivery Mode", m_DeliveryMode);
            if (EditorGUI.EndChangeCheck())
            {
                foreach (var s in otherSchemas)
                {
                    ((AssetPackGroupSchema)s).m_DeliveryMode = m_DeliveryMode;
                }
            }
            EditorGUI.showMixedValue = false;

            so.ApplyModifiedProperties();
        }
Exemple #8
0
        /// <summary>
        /// Package the specified raw assets in the specified folders, keyed by <see cref="TextureCompressionFormat"/>,
        /// in an <see cref="AssetPack"/> with the specified delivery mode.
        /// When using Play Asset Delivery APIs, only the folder for the device's preferred texture compression format
        /// will be delivered.
        /// </summary>
        /// <param name="assetPackName">The name of the asset pack.</param>
        /// <param name="compressionFormatToAssetPackDirectoryPath">
        /// A dictionary from <see cref="TextureCompressionFormat"/> to the path of directories of files that will be
        /// directly copied into the asset pack during app bundle creation.</param>
        /// <param name="deliveryMode">The <see cref="AssetPackDeliveryMode"/> for the asset pack.</param>
        /// <exception cref="ArgumentException">If the dictionary or asset pack name is invalid.</exception>
        public void AddAssetsFolders(
            string assetPackName,
            IDictionary <TextureCompressionFormat, string> compressionFormatToAssetPackDirectoryPath,
            AssetPackDeliveryMode deliveryMode)
        {
            if (compressionFormatToAssetPackDirectoryPath.Count == 0)
            {
                throw new ArgumentException("Dictionary should contain at least one path");
            }

            if (compressionFormatToAssetPackDirectoryPath.All(kvp => kvp.Key != TextureCompressionFormat.Default))
            {
                throw new ArgumentException("Dictionary should contain at least one Default compression path");
            }

            CheckAssetPackName(assetPackName);
            AssetPacks[assetPackName] = new AssetPack
            {
                DeliveryMode = deliveryMode,
                CompressionFormatToAssetPackDirectoryPath =
                    new Dictionary <TextureCompressionFormat, string>(compressionFormatToAssetPackDirectoryPath)
            };
        }
        /// <summary>
        /// Evaluates whether to set any <see cref="Errors"/> based on problems with this variant's dependencies.
        /// </summary>
        /// <param name="deliveryMode">The delivery mode of this asset pack.</param>
        /// <param name="tryGetDependency">A function returning the asset pack for the given dependency name,
        /// along with the delivery mode of the asset pack.</param>
        public void CheckDependencyErrors(AssetPackDeliveryMode deliveryMode, TryGetDependency tryGetDependency)
        {
            if (deliveryMode == AssetPackDeliveryMode.DoNotPackage)
            {
                return;
            }

            foreach (var dependencyName in AllDependencies)
            {
                AssetBundleVariant    dependencyVariant;
                AssetPackDeliveryMode dependencyDeliveryMode;
                if (!tryGetDependency(dependencyName, out dependencyVariant, out dependencyDeliveryMode))
                {
                    Errors.Add(AssetPackError.DependencyMissing);
                    continue;
                }

                if (dependencyVariant.Errors.Count > 0)
                {
                    Errors.Add(AssetPackError.DependencyError);
                }

                // If this asset pack is marked for delivery, all of its dependencies must be packaged for delivery.
                if (dependencyDeliveryMode == AssetPackDeliveryMode.DoNotPackage)
                {
                    Errors.Add(AssetPackError.DependencyNotPackaged);
                    continue;
                }

                // An asset pack cannot have dependencies on asset packs with later delivery modes,
                // e.g. A FastFollow asset pack cannot depend on an OnDemand asset pack.
                if (deliveryMode < dependencyDeliveryMode)
                {
                    Errors.Add(AssetPackError.DependencyIncompatibleDelivery);
                }
            }
        }
        private XDocument CreateAssetPackManifestXDocument(string packName, AssetPackDeliveryMode deliveryMode)
        {
            if (_assetPackManifestTransformers == null)
            {
                throw new BuildToolNotInitializedException(this);
            }

            var doc = AssetPackManifestHelper.CreateAssetPackManifestXDocument(
                _packageName,
                packName,
                deliveryMode);

            foreach (var transformer in _assetPackManifestTransformers)
            {
                var error = transformer.Transform(doc);
                if (!string.IsNullOrEmpty(error))
                {
                    DisplayBuildError("AndroidManifest configuration", error);
                    break;
                }
            }

            return(doc);
        }
Exemple #11
0
 /// <summary>
 /// Constructor.
 /// </summary>
 public AssetBundlePack(string name, AssetPackDeliveryMode deliveryMode)
 {
     Name         = name;
     DeliveryMode = deliveryMode;
     Variants     = new Dictionary <TextureCompressionFormat, AssetBundleVariant>();
 }