void PrintText(BuildLayout layout) { MemoryStream stream = new MemoryStream(); BuildLayoutPrinter.WriteBundleLayout(stream, layout); string report = Encoding.ASCII.GetString(stream.ToArray()); Debug.Log(report); }
public void WhenAssetHasStreamedData_IsReportedCorrectly() { AddressableAssetGroup group = CreateGroup("Group1"); string prefabGUID = CreateAddressableTexture("t1", group, 256); BuildLayout layout = BuildAndExtractLayout(); Assert.IsTrue(layout.Groups[0].Bundles[0].Files[0].Assets[0].StreamedSize != 0); BuildLayout.SubFile f = layout.Groups[0].Bundles[0].Files[0].SubFiles.First(x => x.Name.EndsWith(".resS")); Assert.IsFalse(f.IsSerializedFile); }
public void WhenAssetImplicitlyPulledIntoBundle_ImplicitEntryAndReferencesCreated() { AddressableAssetGroup group = CreateGroup("Group1"); string prefabGUID = CreateAddressablePrefab("p1", group); string aGUID = CreateAsset("p2"); MakePefabReference(prefabGUID, aGUID); BuildLayout layout = BuildAndExtractLayout(); BuildLayout.DataFromOtherAsset oa = layout.Groups[0].Bundles[0].Files[0].OtherAssets.First(x => x.AssetPath.Contains("p2.prefab")); Assert.AreEqual(aGUID, oa.AssetGuid); }
public void WhenReferencedObjectIdentifiedWithFilename_ObjectRepresentedInDataFromOtherAssets() { using (new SpritePackerScope(SpritePackerMode.BuildTimeOnlyAtlas)) { BuildCache.PurgeCache(false); AddressableAssetGroup group = CreateGroup("Group1"); string textureGUID = CreateSpriteTexture("spritetexture", 256, false); MakeAddressable(group, CreateSpriteAtlas("atlas", textureGUID)); BuildLayout layout = BuildAndExtractLayout(); BuildLayout.DataFromOtherAsset otherAssets = layout.Groups[0].Bundles[0].Files[0].Assets[0].InternalReferencedOtherAssets[0]; Assert.IsTrue(otherAssets.AssetPath.StartsWith("library/atlascache", StringComparison.OrdinalIgnoreCase)); CollectionAssert.Contains(otherAssets.ReferencingAssets, layout.Groups[0].Bundles[0].Files[0].Assets[0]); } }
internal BuildLayout BuildAndExtractLayout() { try { BuildLayout layout = null; BuildLayoutGenerationTask.s_LayoutCompleteCallback = (x) => layout = x; m_Settings.BuildPlayerContentImpl(); return(layout); } finally { BuildLayoutGenerationTask.s_LayoutCompleteCallback = null; } }
/// <summary> /// Runs the build task with the injected context. /// </summary> /// <returns>The success or failure ReturnCode</returns> public ReturnCode Run() { BuildLayout layout = CreateBuildLayout(); Directory.CreateDirectory(Path.GetDirectoryName(kLayoutTextFile)); using (FileStream s = File.Open(kLayoutTextFile, FileMode.Create)) BuildLayoutPrinter.WriteBundleLayout(s, layout); UnityEngine.Debug.Log($"Build layout written to {kLayoutTextFile}"); s_LayoutCompleteCallback?.Invoke(layout); return(ReturnCode.Success); }
public void WhenBundleReferencesAnotherBundle_ExternalReferenceExists() { AddressableAssetGroup group = CreateGroup("Group1"); string prefabGUID = CreateAddressablePrefab("p1", group); AddressableAssetGroup group2 = CreateGroup("Group2"); string g2p1GUID = CreateAddressablePrefab("g2p1", group2); MakePefabReference(prefabGUID, g2p1GUID); BuildLayout layout = BuildAndExtractLayout(); CollectionAssert.Contains(layout.Groups[0].Bundles[0].Dependencies, layout.Groups[1].Bundles[0]); Assert.AreEqual(layout.Groups[0].Bundles[0].Files[0].Assets[0].ExternallyReferencedAssets[0], layout.Groups[1].Bundles[0].Files[0].Assets[0]); }
public void WhenAllContentsOfAnAssetAreStripped_ExplicitAssetHasNoObjects() { AddressableAssetGroup group = CreateGroup("Group1"); string assetPath = $"{TempPath}/testpreset.preset"; Material obj = new Material(Shader.Find("Transparent/Diffuse")); Preset myPreset = new Preset(obj); AssetDatabase.CreateAsset(myPreset, assetPath); GameObject.DestroyImmediate(obj); AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate); string guid = AssetDatabase.AssetPathToGUID(assetPath); MakeAddressable(group, guid); BuildLayout layout = BuildAndExtractLayout(); Assert.AreEqual(0, layout.Groups[0].Bundles[0].Files[0].Assets[0].SerializedSize); }
public static Dictionary <string, object> PlacePrograms2D(List <DeptData> deptData, List <double> kpuProgramWidthList, double minAllowedDim = 5, int designSeed = 5, bool checkAspectRatio = false) { if (deptData == null) { return(null); } List <DeptData> deptDataInp = deptData; deptData = deptDataInp.Select(x => new DeptData(x)).ToList(); // example of deep copy List <List <Polygon2d> > polyPorgsAdded = new List <List <Polygon2d> >(); List <ProgramData> progDataNew = new List <ProgramData>(); for (int i = 0; i < deptData.Count; i++) { DeptData deptItem = deptData[i]; //if (i == 0) if ((deptItem.DepartmentType.IndexOf(BuildLayout.KPU.ToLower()) != -1 || deptItem.DepartmentType.IndexOf(BuildLayout.KPU.ToUpper()) != -1)) { Dictionary <string, object> placedPrimaryProg = BuildLayout.PlaceKPUPrograms(deptData[i].PolyAssignedToDept, deptData[i].ProgramsInDept, kpuProgramWidthList); deptData[i].ProgramsInDept = (List <ProgramData>)placedPrimaryProg["ProgramData"]; } else { Dictionary <string, object> placedSecondaryProg = BuildLayout.PlaceREGPrograms(deptData[i], minAllowedDim, designSeed, checkAspectRatio); if (placedSecondaryProg != null) { deptData[i].ProgramsInDept = (List <ProgramData>)placedSecondaryProg["ProgramData"]; } else { deptData[i].ProgramsInDept = null; } } } List <DeptData> newDeptData = deptData.Select(x => new DeptData(x)).ToList(); // example of deep copy return(new Dictionary <string, object> { { "DeptData", (newDeptData) } }); }
public void WhenBundleContainsMultipleFiles_FilesAndSizesMatchArchiveContent() { AddressableAssetGroup groupScenes = CreateGroup("SceneGroup"); AddressableAssetGroup textureGroup = CreateGroup("TextureGroup"); string scenePath = $"{TempPath}/scene.unity"; Scene scene1 = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene); new GameObject().AddComponent <TestBehaviourWithReference>(); EditorSceneManager.SaveScene(scene1, scenePath); AddressableAssetEntry e = m_Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(scenePath), groupScenes); EditorSceneManager.NewScene(NewSceneSetup.EmptyScene); CreateAddressableTexture("t1", textureGroup, 256); BuildLayout layout = BuildAndExtractLayout(); BundledAssetGroupSchema schema = m_Settings.groups.First(x => x.HasSchema <BundledAssetGroupSchema>()).GetSchema <BundledAssetGroupSchema>(); string path = schema.BuildPath.GetValue(m_Settings); foreach (BuildLayout.Bundle bundle in layout.Groups.SelectMany(x => x.Bundles)) { AssertEditorBundleDetailsMatchPhysicalBundle(Path.Combine(path, bundle.Name), bundle); } }
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); }
[MultiReturn(new[] { "DeptData", "LeftOverPolys" })]//"CirculationPolys", "OtherDeptMainPoly" public static Dictionary <string, object> PlaceDepartments2D(List <DeptData> deptData, List <Polygon2d> buildingOutline, List <double> kpuDepthList, List <double> kpuWidthList, double acceptableWidth, double polyDivision = 8, int designSeed = 50, bool noExternalWall = false, bool unlimitedKPU = true, bool mode3D = false, double totalBuildingHeight = 60, double avgFloorHeight = 15) { if (polyDivision >= 1 && polyDivision < 30) { BuildLayout.SPACING = polyDivision; BuildLayout.SPACING2 = polyDivision; } double circulationFreq = 8; List <DeptData> deptDataInp = deptData; deptData = deptDataInp.Select(x => new DeptData(x)).ToList(); // example of deep copy Dictionary <string, object> deptArrangement = new Dictionary <string, object>(); double count = 0, eps = 5; Random rand = new Random(); bool deptPlaced = false; Random ran = new Random(designSeed); bool stackOptionsDept = deptData[0].StackingOptions; bool stackOptionsProg = deptData[0].ProgramsInDept[0].StackingOptions; while (deptPlaced == false && count < BuildLayout.MAXCOUNT)//MAXCOUNT { double parameter = BasicUtility.RandomBetweenNumbers(ran, 0.9, 0.5); if (!stackOptionsDept) { parameter = 0; } //parameter = 0; Trace.WriteLine("PLACE DEPT STARTS , Lets arrange dept again ++++++++++++++++ : " + count); deptArrangement = BuildLayout.DeptPlacer(deptData, buildingOutline, kpuDepthList, kpuWidthList, acceptableWidth, circulationFreq, designSeed, noExternalWall, unlimitedKPU, stackOptionsDept, stackOptionsProg, parameter); if (deptArrangement != null) { List <DeptData> deptDataUpdated = (List <DeptData>)deptArrangement["DeptData"]; List <List <Polygon2d> > deptAllPolys = new List <List <Polygon2d> >(); for (int i = 0; i < deptDataUpdated.Count; i++) { deptAllPolys.Add(deptDataUpdated[i].PolyAssignedToDept); } List <Polygon2d> deptPolysTogether = new List <Polygon2d>(); for (int i = 0; i < deptAllPolys.Count; i++) { if (ValidateObject.CheckPolyList(deptAllPolys[i])) { deptPolysTogether.AddRange(deptAllPolys[i]); } } if (deptAllPolys.Count > 0) { Trace.WriteLine("dept arrangement not null, lets check further"); } for (int i = 0; i < deptAllPolys.Count; i++) { List <Polygon2d> eachDeptPoly = deptAllPolys[i]; if (ValidateObject.CheckPolyList(eachDeptPoly)) { deptPlaced = true; } else { deptPlaced = false; Trace.WriteLine("dept arrangement bad polys, rejected"); break; } bool orthoResult = ValidateObject.CheckPolygon2dListOrtho(deptPolysTogether, eps); Trace.WriteLine("The poly formed is : " + orthoResult); if (orthoResult) { deptPlaced = true; } else { deptPlaced = false; Trace.WriteLine("dept arrangement non orthogonal, rejected"); break; } } } else { deptPlaced = false; designSeed += 1; Trace.WriteLine("DeptPlacer returned null, rejected for: " + count); } count += 1; Trace.WriteLine(" EXIT PLACE DEPARTMENTS +++++++++++++++++++++++++++++++++"); }// end of while loop return(deptArrangement); }