protected sealed override bool Generate(SessionTemplateGeneratorParameters parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }
            parameters.Validate();

            var logger  = parameters.Logger;
            var name    = parameters.Name;
            var session = parameters.Session;

            // Log progress
            var projectName = name;

            ProjectTemplateGeneratorHelper.Progress(logger, $"Generating {projectName}...", 0, 1);

            // Generate the library
            List <string> generatedFiles;

            ProjectTemplateGeneratorHelper.AddOption(parameters, "Platforms", AssetRegistry.SupportedPlatforms);
            var project = ProjectTemplateGeneratorHelper.GenerateTemplate(parameters, "ProjectLibrary/ProjectLibrary.ttproj", projectName, PlatformType.Shared, null, ProjectType.Library, out generatedFiles);

            session.Projects.Add(project);

            // Load missing references
            session.LoadMissingReferences(parameters.Logger);

            // Log done
            ProjectTemplateGeneratorHelper.Progress(logger, "Done", 1, 1);
            return(true);
        }
        public sealed override bool Run(PackageTemplateGeneratorParameters parameters)
        {
            if (parameters == null) throw new ArgumentNullException(nameof(parameters));
            parameters.Validate();

            var logger = parameters.Logger;
            var name = parameters.Name;
            var package = parameters.Package;

            // Make sure we have a shared profile
            var sharedProfile = package.Profiles.FindSharedProfile();
            if (sharedProfile == null)
            {
                sharedProfile = PackageProfile.NewShared();
                package.Profiles.Add(sharedProfile);
            }

            // Log progress
            var projectName = name;
            ProjectTemplateGeneratorHelper.Progress(logger, $"Generating {projectName}...", 0, 1);

            // Generate the library
            List<string> generatedFiles;
            ProjectTemplateGeneratorHelper.AddOption(parameters, "Platforms", AssetRegistry.SupportedPlatforms);
            var projectGameRef = ProjectTemplateGeneratorHelper.GenerateTemplate(parameters, package, "ProjectLibrary/ProjectLibrary.ttproj", projectName, PlatformType.Shared, null, ProjectType.Library, out generatedFiles);
            projectGameRef.Type = ProjectType.Library;
            sharedProfile.ProjectReferences.Add(projectGameRef);

            // Log done
            ProjectTemplateGeneratorHelper.Progress(logger, "Done", 1, 1);
            return true;
        }
        private static ProjectTemplate PrepareTemplate(PackageTemplateGeneratorParameters parameters, UFile templateRelativePath, PlatformType platformType, string currentProfile, GraphicsPlatform?graphicsPlatform, ProjectType projectType)
        {
            ProjectTemplateGeneratorHelper.AddOption(parameters, "Platforms", parameters.GetTag(PlatformsKey).Select(x => x.Platform).ToList());
            ProjectTemplateGeneratorHelper.AddOption(parameters, "CurrentPlatform", platformType);
            ProjectTemplateGeneratorHelper.AddOption(parameters, "CurrentProfile", currentProfile);
            ProjectTemplateGeneratorHelper.AddOption(parameters, "Orientation", parameters.GetTag(OrientationKey));
            var package = parameters.Package;

            return(ProjectTemplateGeneratorHelper.PrepareTemplate(parameters, package, templateRelativePath, platformType, graphicsPlatform, projectType));
        }
示例#4
0
        public sealed override bool Run(PackageTemplateGeneratorParameters parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            var logger  = parameters.Logger;
            var name    = parameters.Name;
            var package = parameters.Package;

            // Generate executable projects for each platform
            var sharedProfile = package.Profiles.FindSharedProfile();

            // TODO: this is not a safe way to get a game project see PDX-1128
            var gameProjectRef = FindSharedGameProject(package, sharedProfile, logger);

            if (gameProjectRef == null)
            {
                return(false);
            }

            // We need to patch the previous game project in order to regenerate property groups
            var templateGameLibrary     = PrepareTemplate(parameters, "ProjectLibrary.Game/ProjectLibrary.Game.ttproj", PlatformType.Shared, null, null, ProjectType.Library);
            var options                 = ProjectTemplateGeneratorHelper.GetOptions(parameters);
            var newGameTargetFrameworks = templateGameLibrary.GeneratePart(@"..\Common.TargetFrameworks.targets.t4", logger, options);

            PatchGameProject(newGameTargetFrameworks, gameProjectRef.Location.FullPath);

            // Generate missing platforms
            bool forceGenerating = parameters.GetTag(ForcePlatformRegenerationKey);

            ProjectTemplateGeneratorHelper.UpdatePackagePlatforms(parameters, parameters.GetTag(PlatformsKey), parameters.GetTag(OrientationKey), gameProjectRef.Id, name, package, forceGenerating);

            // Save the session after the update
            // FIXME: Saving like this is not supported anymore - let's not save for now be we should provide a proper way to save!
            //var result = package.Session.Save();
            //result.CopyTo(logger);

            // Log done
            ProjectTemplateGeneratorHelper.Progress(logger, "Done", 1, 1);
            return(true);
        }
        public override async Task <bool> PrepareForRun(PackageTemplateGeneratorParameters parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }
            parameters.Validate();

            var package           = parameters.Package;
            var gameSettingsAsset = package.GetGameSettingsAsset();

            if (gameSettingsAsset == null)
            {
                parameters.Logger.Error($"Could not find game settings asset at location [{GameSettingsAsset.GameSettingsLocation}]");
                return(false);
            }

            // If there are no executable/shared projects in this package, we can't work on it
            var existingPlatformTypesWithExe = new HashSet <PlatformType>(AssetRegistry.SupportedPlatforms.Where(x => File.Exists(ProjectTemplateGeneratorHelper.GeneratePlatformProjectLocation(parameters.Name, parameters.Package, x))).Select(x => x.Type));

            if (!(package.Container is SolutionProject project) || project.Platform != PlatformType.Shared)
            {
                parameters.Logger.Error("The selected package does not contain a shared profile");
                return(false);
            }

            var defaultNamespace = GetDefaultNamespace(parameters);

            if (parameters.Unattended)
            {
                if (!parameters.HasTag(PlatformsKey))
                {
                    throw new InvalidOperationException("The platforms must be set with SetPlatforms before calling PrepareForRun if DontAskForPlatforms is true.");
                }
                parameters.SetTag(ForcePlatformRegenerationKey, true);
            }
            else
            {
                var window = new UpdatePlatformsWindow(existingPlatformTypesWithExe)
                {
                    ForcePlatformRegenerationVisible = parameters.TryGetTag(ForcePlatformRegenerationKey)
                };

                await window.ShowModal();

                if (window.Result == DialogResult.Cancel)
                {
                    return(false);
                }

                parameters.SetTag(PlatformsKey, new List <SelectedSolutionPlatform>(window.SelectedPlatforms));
                parameters.SetTag(ForcePlatformRegenerationKey, window.ForcePlatformRegeneration);
            }
            parameters.SetTag(OrientationKey, (DisplayOrientation)gameSettingsAsset.GetOrCreate <RenderingSettings>().DisplayOrientation);
            parameters.Namespace = defaultNamespace;

            return(true);
        }
示例#6
0
        /// <summary>
        /// Copy any referenced asset packages to the project's folder
        /// </summary>
        private static void CopyAssetPacks(SessionTemplateGeneratorParameters parameters)
        {
            var logger = parameters.Logger;

            var installDir       = DirectoryHelper.GetInstallationDirectory("Xenko");
            var assetPackagesDir = (DirectoryHelper.IsRootDevDirectory(installDir)) ?
                                   UDirectory.Combine(installDir, @"samples\Templates\Packs") :
                                   UDirectory.Combine(ProjectTemplateGeneratorHelper.GetTemplateDataDirectory(parameters.Description).GetParent(), @"Samples\Templates\Packs");
            var assetPacks = parameters.TryGetTag(AssetsKey);

            if (assetPacks == null)
            {
                return;
            }

            try
            {
                var outAssetDir    = UPath.Combine(parameters.OutputDirectory, (UDirectory)"Assets");
                var outResourceDir = UPath.Combine(parameters.OutputDirectory, (UDirectory)"Resources");

                foreach (var uDirectory in assetPacks)
                {
                    var packageDir = UDirectory.Combine(assetPackagesDir, uDirectory);

                    var inputAssetDir = UDirectory.Combine(packageDir, "Assets");
                    foreach (var directory in FileUtility.EnumerateDirectories(inputAssetDir, SearchDirection.Down))
                    {
                        foreach (var file in directory.GetFiles())
                        {
                            var relativeFile = new UFile(file.FullName).MakeRelative(inputAssetDir);

                            var outputFile          = UPath.Combine(outAssetDir, relativeFile);
                            var outputFileDirectory = outputFile.GetParent();
                            if (!Directory.Exists(outputFileDirectory))
                            {
                                Directory.CreateDirectory(outputFileDirectory);
                            }

                            File.Copy(file.FullName, outputFile, true);
                        }
                    }

                    var inputResourceDir = UDirectory.Combine(packageDir, "Resources");
                    foreach (var directory in FileUtility.EnumerateDirectories(inputResourceDir, SearchDirection.Down))
                    {
                        foreach (var file in directory.GetFiles())
                        {
                            var relativeFile = new UFile(file.FullName).MakeRelative(inputResourceDir);

                            var outputFile = UPath.Combine(outResourceDir, relativeFile);
                            {   // Create the output directory if needed
                                var outputFileDirectory = outputFile.GetParent();
                                if (!Directory.Exists(outputFileDirectory))
                                {
                                    Directory.CreateDirectory(outputFileDirectory);
                                }
                            }

                            File.Copy(file.FullName, outputFile, true);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error("Unexpected exception while copying asset packages", ex);
            }
        }
示例#7
0
        /// <summary>
        /// Creates default scene, with a ground plane, sphere, directional light and camera.
        /// If graphicsProfile is 10+, add cubemap light, otherwise ambient light.
        /// Also properly setup graphics pipeline depending on if HDR is set or not
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        /// <param name="package">The package in which to create these assets.</param>
        private void CreateAndSetNewScene(SessionTemplateGeneratorParameters parameters, Package package, ProjectReference projectGameReference, string projectGameName)
        {
            var logger = parameters.Logger;

            var graphicsProfile = parameters.GetTag(GraphicsProfileKey);
            var isHDR           = parameters.GetTag(IsHDRKey);

            if (graphicsProfile < GraphicsProfile.Level_10_0)
            {
                isHDR = false;
            }

            // Create the material for the sphere
            var sphereMaterial = new MaterialAsset
            {
                Attributes =
                {
                    Diffuse      = new MaterialDiffuseMapFeature(new ComputeColor(Color.FromBgra(0xFF8C8C8C))),
                    DiffuseModel = new MaterialDiffuseLambertModelFeature(),
                }
            };

            if (isHDR)
            {
                // Create HDR part of material
                sphereMaterial.Attributes.Specular      = new MaterialMetalnessMapFeature(new ComputeFloat(1.0f));
                sphereMaterial.Attributes.SpecularModel = new MaterialSpecularMicrofacetModelFeature();
                sphereMaterial.Attributes.MicroSurface  = new MaterialGlossinessMapFeature(new ComputeFloat(0.65f));
            }

            var sphereMaterialAssetItem = new AssetItem("Sphere Material", sphereMaterial);

            package.Assets.Add(sphereMaterialAssetItem);
            sphereMaterialAssetItem.IsDirty = true;

            // Create the sphere model
            var sphereModel = new ProceduralModelAsset
            {
                Type = new SphereProceduralModel
                {
                    MaterialInstance = { Material = AttachedReferenceManager.CreateProxyObject <Material>(sphereMaterialAssetItem.Id, sphereMaterialAssetItem.Location) },
                    Tessellation     = 30,
                },
            };
            var sphereModelAssetItem = new AssetItem("Sphere", sphereModel);

            package.Assets.Add(sphereModelAssetItem);
            sphereModelAssetItem.IsDirty = true;

            // Create sphere entity
            var sphereEntity = new Entity("Sphere")
            {
                new ModelComponent(AttachedReferenceManager.CreateProxyObject <Model>(sphereModelAssetItem.Id, sphereModelAssetItem.Location))
            };

            sphereEntity.Transform.Position = new Vector3(0.0f, 0.5f, 0.0f);

            // Create the material for the ground
            var groundMaterial = new MaterialAsset
            {
                Attributes =
                {
                    Diffuse      = new MaterialDiffuseMapFeature(new ComputeColor(Color.FromBgra(0xFF242424))),
                    DiffuseModel = new MaterialDiffuseLambertModelFeature(),
                }
            };

            if (isHDR)
            {
                // Create HDR part of material
                groundMaterial.Attributes.Specular      = new MaterialMetalnessMapFeature(new ComputeFloat(0.0f));
                groundMaterial.Attributes.SpecularModel = new MaterialSpecularMicrofacetModelFeature();
                groundMaterial.Attributes.MicroSurface  = new MaterialGlossinessMapFeature(new ComputeFloat(0.1f));
            }

            var groundMaterialAssetItem = new AssetItem("Ground Material", groundMaterial);

            package.Assets.Add(groundMaterialAssetItem);
            groundMaterialAssetItem.IsDirty = true;

            // Create the ground model
            var groundModel = new ProceduralModelAsset
            {
                Type = new PlaneProceduralModel
                {
                    Size             = new Vector2(10.0f, 10.0f),
                    MaterialInstance = { Material = AttachedReferenceManager.CreateProxyObject <Material>(groundMaterialAssetItem.Id, groundMaterialAssetItem.Location) },
                },
            };
            var groundModelAssetItem = new AssetItem("Ground", groundModel);

            package.Assets.Add(groundModelAssetItem);
            groundModelAssetItem.IsDirty = true;

            // Create the ground entity
            var groundEntity = new Entity("Ground")
            {
                new ModelComponent(AttachedReferenceManager.CreateProxyObject <Model>(groundModelAssetItem.Id, groundModelAssetItem.Location))
            };

            // Copy file in Resources
            var skyboxFilename = (UFile)(isHDR ? "skybox_texture_hdr.dds" : "skybox_texture_ldr.dds");

            try
            {
                var resources = UPath.Combine(parameters.OutputDirectory, (UDirectory)"Resources");
                Directory.CreateDirectory(resources.ToWindowsPath());

                // TODO: Hardcoded due to the fact that part of the template is in another folder in dev build
                // We might want to extend TemplateFolder to support those cases
                var dataDirectory  = ProjectTemplateGeneratorHelper.GetTemplateDataDirectory(parameters.Description);
                var skyboxFullPath = UPath.Combine(dataDirectory, skyboxFilename).ToWindowsPath();
                File.Copy(skyboxFullPath, UPath.Combine(resources, skyboxFilename).ToWindowsPath(), true);
            }
            catch (Exception ex)
            {
                logger.Error("Unexpected exception while copying cubemap", ex);
            }

            // Create the texture asset
            var skyboxTextureAsset = new TextureAsset {
                Source = Path.Combine(@"..\..\Resources", skyboxFilename), IsCompressed = isHDR, Type = new ColorTextureType {
                    UseSRgbSampling = false
                }
            };
            var skyboxTextureAssetItem = new AssetItem("Skybox texture", skyboxTextureAsset);

            package.Assets.Add(skyboxTextureAssetItem);
            skyboxTextureAssetItem.IsDirty = true;

            // Create the skybox asset
            var skyboxAsset = new SkyboxAsset
            {
                CubeMap = AttachedReferenceManager.CreateProxyObject <Texture>(skyboxTextureAssetItem.Id, skyboxTextureAssetItem.Location)
            };
            var skyboxAssetItem = new AssetItem("Skybox", skyboxAsset);

            package.Assets.Add(skyboxAssetItem);
            skyboxAssetItem.IsDirty = true;

            // Create the scene
            var defaultSceneAsset = isHDR ? SceneHDRFactory.Create() : SceneLDRFactory.Create();

            defaultSceneAsset.Hierarchy.Parts.Add(new EntityDesign(groundEntity));
            defaultSceneAsset.Hierarchy.RootParts.Add(groundEntity);

            defaultSceneAsset.Hierarchy.Parts.Add(new EntityDesign(sphereEntity));
            defaultSceneAsset.Hierarchy.RootParts.Add(sphereEntity);

            var sceneAssetItem = new AssetItem(GameSettingsAsset.DefaultSceneLocation, defaultSceneAsset);

            package.Assets.Add(sceneAssetItem);
            sceneAssetItem.IsDirty = true;

            // Sets the scene created as default in the shared profile
            var gameSettingsAsset = package.Assets.Find(GameSettingsAsset.GameSettingsLocation);

            if (gameSettingsAsset != null)
            {
                ((GameSettingsAsset)gameSettingsAsset.Asset).DefaultScene = AttachedReferenceManager.CreateProxyObject <Scene>(sceneAssetItem.Id, sceneAssetItem.Location);
                gameSettingsAsset.IsDirty = true;
            }

            var skyboxEntity = defaultSceneAsset.Hierarchy.Parts.Select(x => x.Value.Entity).Single(x => x.Name == SceneBaseFactory.SkyboxEntityName);

            skyboxEntity.Get <BackgroundComponent>().Texture = skyboxAsset.CubeMap;
            if (isHDR)
            {
                skyboxEntity.Get <LightComponent>().Type = new LightSkybox
                {
                    Skybox = AttachedReferenceManager.CreateProxyObject <Skybox>(skyboxAssetItem.Id, skyboxAssetItem.Location)
                };
            }

            var cameraEntity       = defaultSceneAsset.Hierarchy.Parts.Select(x => x.Value.Entity).Single(x => x.Name == SceneBaseFactory.CameraEntityName);
            var graphicsCompositor = package.Assets.Select(x => x.Asset).OfType <GraphicsCompositorAsset>().Single();

            cameraEntity.Components.Get <CameraComponent>().Slot = graphicsCompositor.Cameras.Single().ToSlotId();

            // Let's add camera script
            CreateCameraScript(parameters, package, projectGameReference, projectGameName, cameraEntity, sceneAssetItem);
        }
示例#8
0
        protected override bool Generate(SessionTemplateGeneratorParameters parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }
            // Structure of files to generate:
            //     $Name$.xkpkg
            //     $Name$.targets
            //     Assets\
            //     $Name$.Game\
            //     $Name$.Windows\
            //     $Name$.Android\
            //     $Name$.iOS\

            var logger          = parameters.Logger;
            var platforms       = parameters.GetTag(PlatformsKey);
            var name            = parameters.Name;
            var outputDirectory = parameters.OutputDirectory;
            var orientation     = parameters.GetTag(OrientationKey);

            // Generate the package
            var package = NewPackageTemplateGenerator.GeneratePackage(parameters);

            // Generate projects for this package
            var session = parameters.Session;

            var sharedProfile = package.Profiles.FindSharedProfile();

            // Setup the assets folder
            Directory.CreateDirectory(UPath.Combine(outputDirectory, (UDirectory)"Assets/Shared"));

            //write gitignore
            WriteGitIgnore(parameters);

            var previousCurrent = session.CurrentPackage;

            session.CurrentPackage = package;

            var projectGameName = Utilities.BuildValidNamespaceName(name) + ".Game";

            var stepIndex = 0;
            var stepCount = platforms.Count + 1;

            // Log progress
            ProjectTemplateGeneratorHelper.Progress(logger, $"Generating {projectGameName}...", stepIndex++, stepCount);

            // Generate the Game library
            var projectGameReference = ProjectTemplateGeneratorHelper.GenerateTemplate(parameters, platforms, package, "ProjectLibrary.Game/ProjectLibrary.Game.ttproj", projectGameName, PlatformType.Shared, null, null, ProjectType.Library, orientation);

            projectGameReference.Type = ProjectType.Library;
            sharedProfile.ProjectReferences.Add(projectGameReference);

            // Add Effects as an asset folder in order to load xksl
            sharedProfile.AssetFolders.Add(new AssetFolder(projectGameName + "/Effects"));

            // Generate executable projects for each platform
            ProjectTemplateGeneratorHelper.UpdatePackagePlatforms(parameters, platforms, orientation, projectGameReference.Id, name, package, false);

            // Add asset packages
            CopyAssetPacks(parameters);

            // Load assets from HDD
            package.LoadTemporaryAssets(logger);

            // Validate assets
            package.ValidateAssets(true, false, logger);

            // Setup GraphicsCompositor using DefaultGraphicsCompositor
            var graphicsProfile      = parameters.GetTag(GraphicsProfileKey);
            var defaultCompositorUrl = graphicsProfile >= GraphicsProfile.Level_10_0 ? XenkoPackageUpgrader.DefaultGraphicsCompositorLevel10Url : XenkoPackageUpgrader.DefaultGraphicsCompositorLevel9Url;
            var defaultCompositor    = session.FindAsset(defaultCompositorUrl);

            var graphicsCompositor = new AssetItem("GraphicsCompositor", defaultCompositor.CreateDerivedAsset());

            package.Assets.Add(graphicsCompositor);
            graphicsCompositor.IsDirty = true;

            // Setup GameSettingsAsset
            var gameSettingsAsset = GameSettingsFactory.Create();

            gameSettingsAsset.GetOrCreate <EditorSettings>().RenderingMode = parameters.GetTag(IsHDRKey) ? RenderingMode.HDR : RenderingMode.LDR;
            gameSettingsAsset.GraphicsCompositor = AttachedReferenceManager.CreateProxyObject <GraphicsCompositor>(graphicsCompositor.ToReference());

            var renderingSettings = gameSettingsAsset.GetOrCreate <RenderingSettings>();

            renderingSettings.DefaultGraphicsProfile = parameters.GetTag(GraphicsProfileKey);
            renderingSettings.DisplayOrientation     = (RequiredDisplayOrientation)orientation;

            var gameSettingsAssetItem = new AssetItem(GameSettingsAsset.GameSettingsLocation, gameSettingsAsset);

            package.Assets.Add(gameSettingsAssetItem);
            gameSettingsAssetItem.IsDirty = true;

            // Add assets to the package
            AddAssets(parameters, package, projectGameReference, projectGameName);

            // Log done
            ProjectTemplateGeneratorHelper.Progress(logger, "Done", stepCount, stepCount);

            session.CurrentPackage = previousCurrent;
            return(true);
        }
示例#9
0
        protected override bool Generate(SessionTemplateGeneratorParameters parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }
            // Structure of files to generate:
            //     $Name$.sdpkg
            //     $Name$.targets
            //     Assets\
            //     $Name$.Game\
            //     $Name$.Windows\
            //     $Name$.Android\
            //     $Name$.iOS\

            var logger          = parameters.Logger;
            var platforms       = parameters.GetTag(PlatformsKey);
            var name            = parameters.Name;
            var outputDirectory = parameters.OutputDirectory;
            var orientation     = parameters.GetTag(OrientationKey);

            // Generate the package
            //var package = NewPackageTemplateGenerator.GeneratePackage(parameters);

            // Generate projects for this package
            var session = parameters.Session;

            var projectGameName = Utilities.BuildValidNamespaceName(name);

            var stepIndex = 0;
            var stepCount = platforms.Count + 1;

            // Log progress
            ProjectTemplateGeneratorHelper.Progress(logger, $"Generating {projectGameName}...", stepIndex++, stepCount);

            // Generate the Game library
            var project = ProjectTemplateGeneratorHelper.GenerateTemplate(parameters, platforms, "ProjectLibrary.Game/ProjectLibrary.Game.ttproj", projectGameName, PlatformType.Shared, null, ProjectType.Library, orientation);
            var package = project.Package;

            //write gitignore
            WriteGitIgnore(parameters);

            // Setup the assets folder
            //Directory.CreateDirectory(UPath.Combine(package.RootDirectory, (UDirectory)"Assets/Shared"));

            session.Projects.Add(project);

            // Load missing references
            session.LoadMissingDependencies(parameters.Logger);
            // Load dependency assets (needed for camera script template)
            session.LoadMissingAssets(parameters.Logger, project.FlattenedDependencies.Select(x => x.Package).NotNull());

            // Add Effects as an asset folder in order to load sdsl
            package.AssetFolders.Add(new AssetFolder("Effects"));

            var packageParameters = new PackageTemplateGeneratorParameters
            {
                Name            = package.Meta.Name,
                OutputDirectory = package.FullPath.GetFullDirectory(),
                Description     = parameters.Description,
                Package         = package,
                Logger          = parameters.Logger,
                Namespace       = parameters.Namespace
            };

            // Generate executable projects for each platform
            var platformProjects = ProjectTemplateGeneratorHelper.UpdatePackagePlatforms(packageParameters, platforms, orientation, false).ToList();

            // Add asset packages
            CopyAssetPacks(parameters, package);

            // Create camera script
            var cameraScriptTemplate = TemplateManager.FindTemplates(package.Session).OfType <TemplateAssetDescription>().FirstOrDefault(x => x.DefaultOutputName == CameraScriptDefaultOutputName);

            if (cameraScriptTemplate == null)
            {
                throw new InvalidOperationException($"Could not find template for script '{CameraScriptDefaultOutputName}'");
            }

            var cameraScriptParameters = new AssetTemplateGeneratorParameters(string.Empty)
            {
                Name        = cameraScriptTemplate.DefaultOutputName,
                Description = cameraScriptTemplate,
                Namespace   = parameters.Namespace,
                Package     = package,
                Logger      = logger,
                Unattended  = true,
            };

            ScriptTemplateGenerator.SetClassName(cameraScriptParameters, cameraScriptTemplate.DefaultOutputName);
            if (!ScriptTemplateGenerator.Default.PrepareForRun(cameraScriptParameters).Result || !ScriptTemplateGenerator.Default.Run(cameraScriptParameters))
            {
                throw new InvalidOperationException($"Could not create script '{CameraScriptDefaultOutputName}'");
            }

            // Force save after having created the script
            // Note: We do that AFTER GameSettings is dirty, otherwise it would ask for an assembly reload (game settings saved might mean new graphics API)
            SaveSession(parameters);

            // Load missing references
            session.LoadMissingReferences(parameters.Logger);

            // Setup GraphicsCompositor using DefaultGraphicsCompositor
            var graphicsProfile      = parameters.GetTag(GraphicsProfileKey);
            var defaultCompositorUrl = graphicsProfile >= GraphicsProfile.Level_10_0 ? StridePackageUpgrader.DefaultGraphicsCompositorLevel10Url : StridePackageUpgrader.DefaultGraphicsCompositorLevel9Url;
            var defaultCompositor    = session.FindAsset(defaultCompositorUrl);

            var graphicsCompositor = new AssetItem("GraphicsCompositor", defaultCompositor.CreateDerivedAsset());

            package.Assets.Add(graphicsCompositor);
            graphicsCompositor.IsDirty = true;

            // Setup GameSettingsAsset
            var gameSettingsAsset = GameSettingsFactory.Create();

            gameSettingsAsset.GetOrCreate <EditorSettings>().RenderingMode = parameters.GetTag(IsHDRKey) ? RenderingMode.HDR : RenderingMode.LDR;
            gameSettingsAsset.GraphicsCompositor = AttachedReferenceManager.CreateProxyObject <GraphicsCompositor>(graphicsCompositor.ToReference());

            var renderingSettings = gameSettingsAsset.GetOrCreate <RenderingSettings>();

            renderingSettings.DefaultGraphicsProfile = parameters.GetTag(GraphicsProfileKey);
            renderingSettings.DisplayOrientation     = (RequiredDisplayOrientation)orientation;

            var gameSettingsAssetItem = new AssetItem(GameSettingsAsset.GameSettingsLocation, gameSettingsAsset);

            package.Assets.Add(gameSettingsAssetItem);
            gameSettingsAssetItem.IsDirty = true;

            // Add assets to the package
            AddAssets(parameters, package, projectGameName);

            // Log done
            ProjectTemplateGeneratorHelper.Progress(logger, "Done", stepCount, stepCount);

            // Set current project
            session.CurrentProject = platformProjects.FirstOrDefault(x => x.Platform == PlatformType.Windows) ?? project;

            return(true);
        }