public IEnumerable<IReference> EnumerateCompileTimeDependencies(PackageSession session) { if (Prefab != null) { // Return the prefab itself yield return Prefab; // Then we need to return used models and materials because they affects how the meshes are generated var prefab = session.FindAsset(Prefab.Location)?.Asset as PrefabAsset; if (prefab != null) { // Use a dictionary to ensure each reference is yielded only once var references = new Dictionary<AssetId, IReference>(); foreach (var entity in prefab.Hierarchy.Parts) { // Gather all entities with a model component and a valid model var modelComponent = entity.Entity.Get<ModelComponent>(); if (modelComponent?.Model != null) { var modelReference = AttachedReferenceManager.GetAttachedReference(modelComponent.Model); var model = session.FindAsset(modelReference.Url)?.Asset as IModelAsset; if (model != null) { // Build the list of material for this model var materialList = model.Materials.Select(x => x.MaterialInstance.Material).ToList(); for (var i = 0; i < modelComponent.Materials.Count && i < materialList.Count; i++) foreach (var material in modelComponent.Materials) { // Apply any material override from the model component materialList[material.Key] = material.Value; } // Add the model and the related materials to the list of reference references[modelReference.Id] = modelReference; foreach (var material in materialList) { var materialReference = AttachedReferenceManager.GetAttachedReference(material); references[materialReference.Id] = materialReference; } } } } // Finally return all the referenced models and materials foreach (var reference in references.Values) { yield return reference; } } } }
public IIdentifiable ResolvePart(PackageSession session) { var assetItem = session.FindAsset(BasePartAsset.Id); var asset = assetItem?.Asset as AssetComposite; return(asset?.FindPart(BasePartId)); }
/// <summary> /// Create a <see cref="PackageSession"/> that can be used to compile an <see cref="AssetItem"/> by analyzing and resolving its dependencies. /// </summary> /// <returns>The package packageSession that can be used to compile the asset item.</returns> public static PackageSession CreateCompilePackageFromAsset(this PackageSession session, AssetItem originalAssetItem) { if (originalAssetItem == null) { throw new ArgumentNullException("originalAssetItem"); } // Find the asset from the session var assetItem = session.FindAsset(originalAssetItem.Id); if (assetItem == null) { throw new ArgumentException("Cannot find the specified AssetItem instance in the session"); } // Calculate dependencies var dependencies = session.DependencyManager.ComputeDependencies(assetItem, AssetDependencySearchOptions.Out | AssetDependencySearchOptions.Recursive); var assetItemRootCloned = dependencies.Item.Clone(); // Store the fullpath to the sourcefolder, this avoid us to clone hierarchy of packages assetItemRootCloned.SourceFolder = assetItem.FullPath.GetParent(); // create the compile root package and package session var assetPackageCloned = new Package(); var compilePackageSession = new PackageSession(assetPackageCloned); assetPackageCloned.Assets.Add(assetItemRootCloned); // For each asset item dependency, clone it in the new package foreach (var assetLink in dependencies.LinksOut) { // Only add assets not already added (in case of circular dependencies) if (assetPackageCloned.Assets.Find(assetLink.Item.Id) == null) { // create a copy of the asset item and add it to the appropriate compile package var itemCloned = assetLink.Item.Clone(); // Store the fullpath to the sourcefolder, this avoid us to clone hierarchy of packages itemCloned.SourceFolder = assetLink.Item.FullPath.GetParent(); assetPackageCloned.Assets.Add(itemCloned); } } return(compilePackageSession); }
/// <summary> /// Saves this package and all dirty assets. See remarks. /// </summary> /// <param name="log">The log.</param> /// <exception cref="System.ArgumentNullException">log</exception> /// <remarks>When calling this method directly, it does not handle moving assets between packages. /// Call <see cref="PackageSession.Save" /> instead.</remarks> public void Save(ILogger log) { if (log == null) { throw new ArgumentNullException("log"); } if (FullPath == null) { log.Error(this, null, AssetMessageCode.PackageCannotSave, "null"); return; } // Use relative paths when saving var analysis = new PackageAnalysis(this, new PackageAnalysisParameters() { SetDirtyFlagOnAssetWhenFixingUFile = false, ConvertUPathTo = UPathType.Relative, IsProcessingUPaths = true }); analysis.Run(log); try { // Update source folders UpdateSourceFolders(); if (IsDirty) { try { // Notifies the dependency manager that a package with the specified path is being saved if (session != null && session.HasDependencyManager) { session.DependencyManager.AddFileBeingSaveDuringSessionSave(FullPath); } AssetSerializer.Save(FullPath, this); IsDirty = false; } catch (Exception ex) { log.Error(this, null, AssetMessageCode.PackageCannotSave, ex, FullPath); return; } } foreach (var asset in Assets) { if (asset.IsDirty) { var assetPath = asset.FullPath; try { // Notifies the dependency manager that an asset with the specified path is being saved if (session != null && session.HasDependencyManager) { session.DependencyManager.AddFileBeingSaveDuringSessionSave(assetPath); } // Incject a copy of the base into the current asset when saving var assetBase = asset.Asset.Base; if (assetBase != null && !assetBase.IsRootImport) { var assetBaseItem = session != null?session.FindAsset(assetBase.Id) : Assets.Find(assetBase.Id); if (assetBaseItem != null) { var newBase = (Asset)AssetCloner.Clone(assetBaseItem.Asset); newBase.Base = null; asset.Asset.Base = new AssetBase(asset.Asset.Base.Location, newBase); } } AssetSerializer.Save(assetPath, asset.Asset); asset.IsDirty = false; } catch (Exception ex) { log.Error(this, asset.ToReference(), AssetMessageCode.AssetCannotSave, ex, assetPath); } } } Assets.IsDirty = false; // Save properties like the Paradox version used PackageSessionHelper.SaveProperties(this); } finally { // Rollback all relative UFile to absolute paths analysis.Parameters.ConvertUPathTo = UPathType.Absolute; analysis.Run(); } }
public IEnumerable<IReference> EnumerateCompileTimeDependencies(PackageSession session) { if (Scene != null) { var reference = AttachedReferenceManager.GetAttachedReference(Scene); var sceneAsset = (SceneAsset)session.FindAsset(reference.Url)?.Asset; var referencedColliderShapes = new HashSet<AssetId>(); // Find collider assets to reference if (sceneAsset != null) { List<Entity> sceneEntities = sceneAsset.Hierarchy.Parts.Select(x => x.Entity).ToList(); foreach (var entity in sceneEntities) { StaticColliderComponent collider = entity.Get<StaticColliderComponent>(); bool colliderEnabled = collider != null && ((CollisionFilterGroupFlags)collider.CollisionGroup & IncludedCollisionGroups) != 0 && collider.Enabled; if (colliderEnabled) { var assetShapes = collider.ColliderShapes.OfType<ColliderShapeAssetDesc>(); foreach (var assetShape in assetShapes) { if (assetShape.Shape == null) continue; // Reference all asset collider shapes reference = AttachedReferenceManager.GetAttachedReference(assetShape.Shape); // Only need to reference each shape once if (referencedColliderShapes.Contains(reference.Id)) continue; yield return new AssetReference(reference.Id, reference.Url); referencedColliderShapes.Add(reference.Id); } } } } } }