diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h index 8412361657..a26c3b0ecf 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h @@ -56,5 +56,7 @@ namespace AzToolsFramework virtual void StartPlayInEditor() = 0; virtual void StopPlayInEditor() = 0; + + virtual void CreateNewLevelPrefab(AZStd::string_view filename) = 0; }; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp index 97c3041de6..b2b36cc318 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp @@ -225,50 +225,19 @@ namespace AzToolsFramework m_rootInstance->SetTemplateSourcePath(relativePath); - bool newLevelFromTemplate = false; - if (templateId == AzToolsFramework::Prefab::InvalidTemplateId) { - AZStd::string watchFolder; - AZ::Data::AssetInfo assetInfo; - bool sourceInfoFound = false; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult( - sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, DefaultLevelTemplateName, - assetInfo, watchFolder); + m_rootInstance->m_containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent()); + HandleEntitiesAdded({ m_rootInstance->m_containerEntity.get() }); - if (sourceInfoFound) + AzToolsFramework::Prefab::PrefabDom dom; + bool success = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, dom); + if (!success) { - AZStd::string fullPath; - AZ::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), fullPath); - - // Get the default prefab and copy the Dom over to the new template being saved - Prefab::TemplateId defaultId = m_loaderInterface->LoadTemplateFromFile(fullPath.c_str()); - Prefab::PrefabDom& dom = m_prefabSystemComponent->FindTemplateDom(defaultId); - - Prefab::PrefabDom levelDefaultDom; - levelDefaultDom.CopyFrom(dom, levelDefaultDom.GetAllocator()); - - Prefab::PrefabDomPath sourcePath("/Source"); - sourcePath.Set(levelDefaultDom, relativePath.c_str()); - - templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(levelDefaultDom)); - newLevelFromTemplate = true; - } - else - { - // Create an empty level since we couldn't find the default template - m_rootInstance->m_containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent()); - HandleEntitiesAdded({ m_rootInstance->m_containerEntity.get() }); - - AzToolsFramework::Prefab::PrefabDom dom; - bool success = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, dom); - if (!success) - { - AZ_Error("Prefab", false, "Failed to convert current root instance into a DOM when saving file '%.*s'", AZ_STRING_ARG(filename)); - return false; - } - templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(dom)); + AZ_Error("Prefab", false, "Failed to convert current root instance into a DOM when saving file '%.*s'", AZ_STRING_ARG(filename)); + return false; } + templateId = m_prefabSystemComponent->AddTemplate(relativePath, AZStd::move(dom)); if (templateId == AzToolsFramework::Prefab::InvalidTemplateId) { @@ -286,13 +255,6 @@ namespace AzToolsFramework m_prefabSystemComponent->RemoveTemplate(prevTemplateId); } - // If we have a new level from a template, we need to make sure to propagate the changes here otherwise - // the entities from the new template won't show up - if (newLevelFromTemplate) - { - m_prefabSystemComponent->PropagateTemplateChanges(templateId); - } - AZStd::string out; if (m_loaderInterface->SaveTemplateToString(m_rootInstance->GetTemplateId(), out)) { @@ -303,6 +265,71 @@ namespace AzToolsFramework return false; } + void PrefabEditorEntityOwnershipService::CreateNewLevelPrefab(AZStd::string_view filename) + { + AZ::IO::Path relativePath = m_loaderInterface->GetRelativePathToProject(filename); + AzToolsFramework::Prefab::TemplateId templateId = m_prefabSystemComponent->GetTemplateIdFromFilePath(relativePath); + + m_rootInstance->SetTemplateSourcePath(relativePath); + + AZStd::string watchFolder; + AZ::Data::AssetInfo assetInfo; + bool sourceInfoFound = false; + AzToolsFramework::AssetSystemRequestBus::BroadcastResult( + sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, DefaultLevelTemplateName, + assetInfo, watchFolder); + + if (sourceInfoFound) + { + AZStd::string fullPath; + AZ::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), fullPath); + + // Get the default prefab and copy the Dom over to the new template being saved + Prefab::TemplateId defaultId = m_loaderInterface->LoadTemplateFromFile(fullPath.c_str()); + Prefab::PrefabDom& dom = m_prefabSystemComponent->FindTemplateDom(defaultId); + + Prefab::PrefabDom levelDefaultDom; + levelDefaultDom.CopyFrom(dom, levelDefaultDom.GetAllocator()); + + Prefab::PrefabDomPath sourcePath("/Source"); + sourcePath.Set(levelDefaultDom, assetInfo.m_relativePath.c_str()); + + templateId = m_prefabSystemComponent->AddTemplate(relativePath, AZStd::move(levelDefaultDom)); + } + else + { + m_rootInstance->m_containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent()); + HandleEntitiesAdded({ m_rootInstance->m_containerEntity.get() }); + + AzToolsFramework::Prefab::PrefabDom dom; + bool success = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, dom); + if (!success) + { + AZ_Error( + "Prefab", false, "Failed to convert current root instance into a DOM when saving file '%.*s'", AZ_STRING_ARG(filename)); + return; + } + templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(dom)); + } + + if (templateId == AzToolsFramework::Prefab::InvalidTemplateId) + { + AZ_Error("Prefab", false, "Couldn't create new template id '%i' when creating new level '%.*s'", templateId, AZ_STRING_ARG(filename)); + return; + } + + Prefab::TemplateId prevTemplateId = m_rootInstance->GetTemplateId(); + m_rootInstance->SetTemplateId(templateId); + + if (prevTemplateId != Prefab::InvalidTemplateId && templateId != prevTemplateId) + { + // Make sure we only have one level template loaded at a time + m_prefabSystemComponent->RemoveTemplate(prevTemplateId); + } + + m_prefabSystemComponent->PropagateTemplateChanges(templateId); + } + Prefab::InstanceOptionalReference PrefabEditorEntityOwnershipService::CreatePrefab( const AZStd::vector& entities, AZStd::vector>&& nestedPrefabInstances, AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h index 606d5f495f..915cafd316 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h @@ -170,6 +170,8 @@ namespace AzToolsFramework void StartPlayInEditor() override; void StopPlayInEditor() override; + void CreateNewLevelPrefab(AZStd::string_view filename) override; + protected: AZ::SliceComponent::SliceInstanceAddress GetOwningSlice() override; diff --git a/Code/Sandbox/Editor/CryEdit.cpp b/Code/Sandbox/Editor/CryEdit.cpp index 0bbc48d5f9..5fd6eb2692 100644 --- a/Code/Sandbox/Editor/CryEdit.cpp +++ b/Code/Sandbox/Editor/CryEdit.cpp @@ -69,6 +69,7 @@ AZ_POP_DISABLE_WARNING #include #include #include +#include #include // AzQtComponents @@ -3105,6 +3106,15 @@ CCryEditApp::ECreateLevelResult CCryEditApp::CreateLevel(const QString& levelNam GetIEditor()->GetDocument()->SetPathName(fullyQualifiedLevelName); GetIEditor()->GetGameEngine()->SetLevelPath(levelPath); + if (usePrefabSystemForLevels) + { + auto* service = AZ::Interface::Get(); + if (service) + { + service->CreateNewLevelPrefab((const char*)fullyQualifiedLevelName.toUtf8()); + } + } + if (GetIEditor()->GetDocument()->Save()) { if (!usePrefabSystemForLevels)