public void WhenCompressionSetForGroups_GetCompressionForIdentifier_ReturnsExpectedCompression() { var bundleToAssetGroup = new Dictionary <string, string>(); var expectedValues = new BuildCompression[] { BuildCompression.Uncompressed, BuildCompression.LZ4, BuildCompression.LZMA, BuildCompression.UncompressedRuntime, BuildCompression.LZ4Runtime }; var bundleNames = new List <string>(); foreach (var en in GetValues(typeof(BundledAssetGroupSchema.BundleCompressionMode))) { var g = Settings.CreateGroup(en.ToString(), true, false, false, null, typeof(BundledAssetGroupSchema)); g.GetSchema <BundledAssetGroupSchema>().Compression = (BundledAssetGroupSchema.BundleCompressionMode)en; var bName = "bundle_" + en; bundleToAssetGroup.Add(bName, g.Guid); bundleNames.Add(bName); } var testParams = new AddressableAssetsBundleBuildParameters(Settings, bundleToAssetGroup, BuildTarget.StandaloneWindows64, BuildTargetGroup.Standalone, "Unused"); for (int i = 0; i < bundleNames.Count; i++) { var comp = testParams.GetCompressionForIdentifier(bundleNames[i]); Assert.AreEqual(expectedValues[i].blockSize, comp.blockSize); Assert.AreEqual(expectedValues[i].compression, comp.compression); Assert.AreEqual(expectedValues[i].level, comp.level); } }
public static extern uint ArchiveAndCompress(ResourceFile[] resourceFiles, string outputBundlePath, UnityEngine.BuildCompression compression, bool stripUnityVersion);
public static uint ArchiveAndCompress(ResourceFile[] resourceFiles, string outputBundlePath, UnityEngine.BuildCompression compression) { return(ArchiveAndCompress(resourceFiles, outputBundlePath, compression, false)); }
private BuildLayout CreateBuildLayout() { LayoutLookupTables lookup = new LayoutLookupTables(); foreach (string bundleName in m_WriteData.FileToBundle.Values.Distinct()) { BuildLayout.Bundle bundle = new BuildLayout.Bundle(); bundle.Name = bundleName; string path = m_Parameters.GetOutputFilePathForIdentifier(bundle.Name); UnityEngine.BuildCompression compression = m_Parameters.GetCompressionForIdentifier(bundle.Name); bundle.FileSize = (ulong)new FileInfo(path).Length; bundle.Compression = compression.compression.ToString(); lookup.Bundles.Add(bundle.Name, bundle); } // create files foreach (KeyValuePair <string, string> fileBundle in m_WriteData.FileToBundle) { BuildLayout.Bundle bundle = lookup.Bundles[fileBundle.Value]; BuildLayout.File f = new BuildLayout.File(); f.Name = fileBundle.Key; WriteResult result = m_Results.WriteResults[f.Name]; foreach (ResourceFile rf in result.resourceFiles) { var sf = new BuildLayout.SubFile(); sf.IsSerializedFile = rf.serializedFile; sf.Name = rf.fileAlias; sf.Size = (ulong)new FileInfo(rf.fileName).Length; f.SubFiles.Add(sf); } bundle.Files.Add(f); lookup.Files.Add(f.Name, f); } // create assets foreach (KeyValuePair <GUID, List <string> > assetFile in m_WriteData.AssetToFiles) { BuildLayout.File file = lookup.Files[assetFile.Value[0]]; BuildLayout.ExplicitAsset a = new BuildLayout.ExplicitAsset(); a.Guid = assetFile.Key.ToString(); a.AssetPath = AssetDatabase.GUIDToAssetPath(a.Guid); file.Assets.Add(a); lookup.GuidToExplicitAsset.Add(a.Guid, a); } Dictionary <string, List <BuildLayout.DataFromOtherAsset> > guidToPulledInBuckets = new Dictionary <string, List <BuildLayout.DataFromOtherAsset> >(); foreach (BuildLayout.File file in lookup.Files.Values) { Dictionary <string, AssetBucket> buckets = new Dictionary <string, AssetBucket>(); WriteResult writeResult = m_Results.WriteResults[file.Name]; List <ObjectSerializedInfo> sceneObjects = new List <ObjectSerializedInfo>(); foreach (ObjectSerializedInfo info in writeResult.serializedObjects) { string sourceGuid = string.Empty; if (info.serializedObject.guid.Empty()) { if (info.serializedObject.filePath.Equals("temp:/assetbundle", StringComparison.OrdinalIgnoreCase)) { file.BundleObjectInfo = new BuildLayout.AssetBundleObjectInfo(); file.BundleObjectInfo.Size = info.header.size; continue; } else if (info.serializedObject.filePath.StartsWith("temp:/preloaddata", StringComparison.OrdinalIgnoreCase)) { file.PreloadInfoSize = (int)info.header.size; continue; } else if (info.serializedObject.filePath.StartsWith("temp:/", StringComparison.OrdinalIgnoreCase)) { sceneObjects.Add(info); continue; } else if (!string.IsNullOrEmpty(info.serializedObject.filePath)) { AssetBucket pathBucket = GetOrCreate(buckets, info.serializedObject.filePath.ToString()); pathBucket.isFilePathBucket = true; pathBucket.objs.Add(info); continue; } } AssetBucket bucket = GetOrCreate(buckets, info.serializedObject.guid.ToString()); bucket.objs.Add(info); } if (sceneObjects.Count > 0) { BuildLayout.ExplicitAsset sceneAsset = file.Assets.First(x => x.AssetPath.EndsWith(".unity")); AssetBucket bucket = GetOrCreate(buckets, sceneAsset.Guid); bucket.objs.AddRange(sceneObjects); } // Update buckets with a reference to their explicit asset file.Assets.ForEach(eAsset => { if (!buckets.TryGetValue(eAsset.Guid, out AssetBucket b)) { b = GetOrCreate(buckets, eAsset.Guid); // some assets might not pull in any objects } b.ExplictAsset = eAsset; }); // Create entries for buckets that are implicitly pulled in Dictionary <string, BuildLayout.DataFromOtherAsset> guidToOtherData = new Dictionary <string, BuildLayout.DataFromOtherAsset>(); foreach (AssetBucket bucket in buckets.Values.Where(x => x.ExplictAsset == null)) { string assetPath = bucket.isFilePathBucket ? bucket.guid : AssetDatabase.GUIDToAssetPath(bucket.guid); if (assetPath.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) || assetPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) { file.MonoScriptCount++; file.MonoScriptSize += bucket.CalcObjectSize(); continue; } var otherData = new BuildLayout.DataFromOtherAsset(); otherData.AssetPath = assetPath; otherData.AssetGuid = bucket.guid; otherData.SerializedSize = bucket.CalcObjectSize(); otherData.StreamedSize = bucket.CalcStreamedSize(); otherData.ObjectCount = bucket.objs.Count; file.OtherAssets.Add(otherData); guidToOtherData[otherData.AssetGuid] = otherData; if (!guidToPulledInBuckets.TryGetValue(otherData.AssetGuid, out List <BuildLayout.DataFromOtherAsset> bucketList)) { bucketList = guidToPulledInBuckets[otherData.AssetGuid] = new List <BuildLayout.DataFromOtherAsset>(); } bucketList.Add(otherData); } // Add references foreach (BuildLayout.ExplicitAsset asset in file.Assets) { AssetBucket bucket = buckets[asset.Guid]; asset.SerializedSize = bucket.CalcObjectSize(); asset.StreamedSize = bucket.CalcStreamedSize(); IEnumerable <ObjectIdentifier> refs = null; if (m_DependencyData.AssetInfo.TryGetValue(new GUID(asset.Guid), out AssetLoadInfo info)) { refs = info.referencedObjects; } else { refs = m_DependencyData.SceneInfo[new GUID(asset.Guid)].referencedObjects; } foreach (string refGUID in refs.Select(x => x.guid.Empty() ? x.filePath : x.guid.ToString()).Distinct()) { if (guidToOtherData.TryGetValue(refGUID, out BuildLayout.DataFromOtherAsset dfoa)) { dfoa.ReferencingAssets.Add(asset); asset.InternalReferencedOtherAssets.Add(dfoa); } else if (buckets.TryGetValue(refGUID, out AssetBucket refBucket)) { asset.InternalReferencedExplicitAssets.Add(refBucket.ExplictAsset); } else if (lookup.GuidToExplicitAsset.TryGetValue(refGUID, out BuildLayout.ExplicitAsset refAsset)) { asset.ExternallyReferencedAssets.Add(refAsset); } } } } BuildLayout layout = new BuildLayout(); // This is the addressables section. Everything above could technically be moved to SBP. { AddressableAssetsBuildContext aaContext = (AddressableAssetsBuildContext)m_AaBuildContext; // Map from GUID to AddrssableAssetEntry Dictionary <string, AddressableAssetEntry> guidToEntry = aaContext.assetEntries.ToDictionary(x => x.guid, x => x); // create groups foreach (AddressableAssetGroup group in aaContext.Settings.groups) { var grp = new BuildLayout.Group(); grp.Name = group.Name; grp.Guid = group.Guid; foreach (AddressableAssetGroupSchema schema in group.Schemas) { var sd = new BuildLayout.SchemaData(); sd.Guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(schema)); sd.Type = schema.GetType().Name.ToString(); BundledAssetGroupSchema bSchema = schema as BundledAssetGroupSchema; if (bSchema != null) { sd.KvpDetails.Add(new Tuple <string, string>("PackingMode", bSchema.BundleMode.ToString())); sd.KvpDetails.Add(new Tuple <string, string>("Compression", bSchema.Compression.ToString())); } grp.Schemas.Add(sd); } lookup.GroupLookup.Add(group.Guid, grp); layout.Groups.Add(grp); } // go through all the bundles and put them in groups foreach (BuildLayout.Bundle b in lookup.Bundles.Values) { if (aaContext.bundleToImmediateBundleDependencies.TryGetValue(b.Name, out List <string> deps)) { b.Dependencies = deps.Select(x => lookup.Bundles[x]).Where(x => b != x).ToList(); } if (aaContext.bundleToExpandedBundleDependencies.TryGetValue(b.Name, out List <string> deps2)) { b.ExpandedDependencies = deps2.Select(x => lookup.Bundles[x]).Where(x => b != x).ToList(); } if (aaContext.bundleToAssetGroup.TryGetValue(b.Name, out string grpName)) { lookup.GroupLookup[grpName].Bundles.Add(b); } else { layout.BuiltInBundles.Add(b); } } // Apply the addressable name to the asset foreach (BuildLayout.ExplicitAsset a in BuildLayoutHelpers.EnumerateAssets(layout)) { if (guidToEntry.TryGetValue(a.Guid, out AddressableAssetEntry entry)) { a.AddressableName = entry.address; } } // The addressables build script can rename the bundles foreach (BuildLayout.Bundle b in BuildLayoutHelpers.EnumerateBundles(layout)) { if (m_BundleNameRemap.TryGetValue(b.Name, out string newName)) { b.Name = newName; } } } return(layout); }