Fixed CreatePrefab to use correct absolute path (#1044)
The initial CreatePrefab flow was trying to go from absolute -> relative -> absolute path before the file had ever been saved, so the relative -> absolute path conversion generated an error and always produced a project-relative path, even if the initial path was in a gem. For example, trying to save "c:/o3de/Gems/Camera/Assets/Entity1.prefab" would instead create "c:/o3de/AutomatedTesting/Entity1.prefab". This change preserves the absolute path throughout the initial creation flow so that the file is saved in the correct location.
This commit is contained in:
@@ -303,6 +303,45 @@ namespace AzToolsFramework
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PrefabLoader::SaveTemplateToFile(TemplateId templateId, AZ::IO::PathView absolutePath)
|
||||||
|
{
|
||||||
|
AZ_Assert(absolutePath.IsAbsolute(), "SaveTemplateToFile requires an absolute path for saving the initial prefab file.");
|
||||||
|
|
||||||
|
const auto& domAndFilepath = StoreTemplateIntoFileFormat(templateId);
|
||||||
|
if (!domAndFilepath)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that the absolute path provided to this matches the relative path saved in the template.
|
||||||
|
// Otherwise, the saved prefab won't be able to be loaded.
|
||||||
|
auto relativePath = GenerateRelativePath(absolutePath);
|
||||||
|
if (relativePath != domAndFilepath->second)
|
||||||
|
{
|
||||||
|
AZ_Error(
|
||||||
|
"Prefab", false,
|
||||||
|
"PrefabLoader::SaveTemplateToFile - "
|
||||||
|
"Failed to save template '%s' to location '%.*s'."
|
||||||
|
"Error: Relative path '%.*s' for location didn't match template name.",
|
||||||
|
domAndFilepath->second.c_str(), AZ_STRING_ARG(absolutePath.Native()), AZ_STRING_ARG(relativePath.Native()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto outcome = AzFramework::FileFunc::WriteJsonFile(domAndFilepath->first, absolutePath);
|
||||||
|
if (!outcome.IsSuccess())
|
||||||
|
{
|
||||||
|
AZ_Error(
|
||||||
|
"Prefab", false,
|
||||||
|
"PrefabLoader::SaveTemplateToFile - "
|
||||||
|
"Failed to save template '%s' to location '%.*s'."
|
||||||
|
"Error: %s",
|
||||||
|
domAndFilepath->second.c_str(), AZ_STRING_ARG(absolutePath.Native()), outcome.GetError().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool PrefabLoader::SaveTemplateToString(TemplateId templateId, AZStd::string& output)
|
bool PrefabLoader::SaveTemplateToString(TemplateId templateId, AZStd::string& output)
|
||||||
{
|
{
|
||||||
const auto& domAndFilepath = StoreTemplateIntoFileFormat(templateId);
|
const auto& domAndFilepath = StoreTemplateIntoFileFormat(templateId);
|
||||||
|
|||||||
@@ -72,6 +72,16 @@ namespace AzToolsFramework
|
|||||||
*/
|
*/
|
||||||
bool SaveTemplate(TemplateId templateId) override;
|
bool SaveTemplate(TemplateId templateId) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a Prefab Template to the provided absolute source path, which needs to match the relative path in the template.
|
||||||
|
* Converts Prefab Template form into .prefab form by collapsing nested Template info
|
||||||
|
* into a source path and patches.
|
||||||
|
* @param templateId Id of the template to be saved
|
||||||
|
* @param absolutePath Absolute path to save the file to
|
||||||
|
* @return bool on whether the operation succeeded or not
|
||||||
|
*/
|
||||||
|
bool SaveTemplateToFile(TemplateId templateId, AZ::IO::PathView absolutePath) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves a Prefab Template into the provided output string.
|
* Saves a Prefab Template into the provided output string.
|
||||||
* Converts Prefab Template form into .prefab form by collapsing nested Template info
|
* Converts Prefab Template form into .prefab form by collapsing nested Template info
|
||||||
|
|||||||
@@ -60,6 +60,16 @@ namespace AzToolsFramework
|
|||||||
*/
|
*/
|
||||||
virtual bool SaveTemplate(TemplateId templateId) = 0;
|
virtual bool SaveTemplate(TemplateId templateId) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a Prefab Template to the provided absolute source path, which needs to match the relative path in the template.
|
||||||
|
* Converts Prefab Template form into .prefab form by collapsing nested Template info
|
||||||
|
* into a source path and patches.
|
||||||
|
* @param templateId Id of the template to be saved
|
||||||
|
* @param absolutePath Absolute path to save the file to
|
||||||
|
* @return bool on whether the operation succeeded or not
|
||||||
|
*/
|
||||||
|
virtual bool SaveTemplateToFile(TemplateId templateId, AZ::IO::PathView absolutePath) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves a Prefab Template into the provided output string.
|
* Saves a Prefab Template into the provided output string.
|
||||||
* Converts Prefab Template form into .prefab form by collapsing nested Template info
|
* Converts Prefab Template form into .prefab form by collapsing nested Template info
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ namespace AzToolsFramework
|
|||||||
m_prefabUndoCache.Destroy();
|
m_prefabUndoCache.Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
PrefabOperationResult PrefabPublicHandler::CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath)
|
PrefabOperationResult PrefabPublicHandler::CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView absolutePath)
|
||||||
{
|
{
|
||||||
EntityList inputEntityList, topLevelEntities;
|
EntityList inputEntityList, topLevelEntities;
|
||||||
AZ::EntityId commonRootEntityId;
|
AZ::EntityId commonRootEntityId;
|
||||||
@@ -76,6 +76,8 @@ namespace AzToolsFramework
|
|||||||
return findCommonRootOutcome;
|
return findCommonRootOutcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AZ_Assert(absolutePath.IsAbsolute(), "CreatePrefab requires an absolute path for saving the initial prefab file.");
|
||||||
|
|
||||||
InstanceOptionalReference instanceToCreate;
|
InstanceOptionalReference instanceToCreate;
|
||||||
{
|
{
|
||||||
// Initialize Undo Batch object
|
// Initialize Undo Batch object
|
||||||
@@ -144,7 +146,8 @@ namespace AzToolsFramework
|
|||||||
|
|
||||||
// Create the Prefab
|
// Create the Prefab
|
||||||
instanceToCreate = prefabEditorEntityOwnershipInterface->CreatePrefab(
|
instanceToCreate = prefabEditorEntityOwnershipInterface->CreatePrefab(
|
||||||
entities, AZStd::move(instancePtrs), filePath, commonRootEntityOwningInstance);
|
entities, AZStd::move(instancePtrs), m_prefabLoaderInterface->GenerateRelativePath(absolutePath),
|
||||||
|
commonRootEntityOwningInstance);
|
||||||
|
|
||||||
if (!instanceToCreate)
|
if (!instanceToCreate)
|
||||||
{
|
{
|
||||||
@@ -254,7 +257,7 @@ namespace AzToolsFramework
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save Template to file
|
// Save Template to file
|
||||||
m_prefabLoaderInterface->SaveTemplate(instanceToCreate->get().GetTemplateId());
|
m_prefabLoaderInterface->SaveTemplateToFile(instanceToCreate->get().GetTemplateId(), absolutePath);
|
||||||
|
|
||||||
return AZ::Success();
|
return AZ::Success();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace AzToolsFramework
|
|||||||
void UnregisterPrefabPublicHandlerInterface();
|
void UnregisterPrefabPublicHandlerInterface();
|
||||||
|
|
||||||
// PrefabPublicInterface...
|
// PrefabPublicInterface...
|
||||||
PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath) override;
|
PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView absolutePath) override;
|
||||||
PrefabOperationResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) override;
|
PrefabOperationResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) override;
|
||||||
PrefabOperationResult SavePrefab(AZ::IO::Path filePath) override;
|
PrefabOperationResult SavePrefab(AZ::IO::Path filePath) override;
|
||||||
PrefabEntityResult CreateEntity(AZ::EntityId parentId, const AZ::Vector3& position) override;
|
PrefabEntityResult CreateEntity(AZ::EntityId parentId, const AZ::Vector3& position) override;
|
||||||
|
|||||||
@@ -46,10 +46,10 @@ namespace AzToolsFramework
|
|||||||
* Create a prefab out of the entities provided, at the path provided.
|
* Create a prefab out of the entities provided, at the path provided.
|
||||||
* Automatically detects descendants of entities, and discerns between entities and child instances.
|
* Automatically detects descendants of entities, and discerns between entities and child instances.
|
||||||
* @param entityIds The entities that should form the new prefab (along with their descendants).
|
* @param entityIds The entities that should form the new prefab (along with their descendants).
|
||||||
* @param filePath The path for the new prefab file.
|
* @param filePath The absolute path for the new prefab file.
|
||||||
* @return An outcome object; on failure, it comes with an error message detailing the cause of the error.
|
* @return An outcome object; on failure, it comes with an error message detailing the cause of the error.
|
||||||
*/
|
*/
|
||||||
virtual PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath) = 0;
|
virtual PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView absolutePath) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate a prefab from a prefab file.
|
* Instantiate a prefab from a prefab file.
|
||||||
|
|||||||
+1
-2
@@ -333,8 +333,7 @@ namespace AzToolsFramework
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto createPrefabOutcome = s_prefabPublicInterface->CreatePrefab(
|
auto createPrefabOutcome = s_prefabPublicInterface->CreatePrefab(selectedEntities, prefabFilePath.data());
|
||||||
selectedEntities, s_prefabLoaderInterface->GenerateRelativePath(prefabFilePath.data()));
|
|
||||||
|
|
||||||
if (!createPrefabOutcome.IsSuccess())
|
if (!createPrefabOutcome.IsSuccess())
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user