/// <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 }; }
/// <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))); }
/// <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(); }
/// <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); }
/// <summary> /// Constructor. /// </summary> public AssetBundlePack(string name, AssetPackDeliveryMode deliveryMode) { Name = name; DeliveryMode = deliveryMode; Variants = new Dictionary <TextureCompressionFormat, AssetBundleVariant>(); }