+1
-1
@@ -295,7 +295,7 @@ namespace AzToolsFramework
|
||||
|
||||
bool usePrefabSystemForLevels = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
||||
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
for (const AzToolsFramework::AssetFileInfo& assetFileInfo : assetFileInfoList.m_fileInfoList)
|
||||
{
|
||||
|
||||
+42
-18
@@ -19,45 +19,69 @@
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Prefab
|
||||
{
|
||||
//! A RootAliasPath can be used to store an alias path that starts from the Prefab EOS root instance.
|
||||
//! The root instance itself is included in the path. These can be used as Instance handles across systems
|
||||
//! that do not have visibility over InstanceOptionalReferences, or that need to store Instance handles
|
||||
//! for longer than just the span of a function without the risk of them going out of scope.
|
||||
using RootAliasPath = AliasPath;
|
||||
}
|
||||
|
||||
class PrefabEditorEntityOwnershipInterface
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(PrefabEditorEntityOwnershipInterface,"{38E764BA-A089-49F3-848F-46018822CE2E}");
|
||||
AZ_RTTI(PrefabEditorEntityOwnershipInterface, "{38E764BA-A089-49F3-848F-46018822CE2E}");
|
||||
|
||||
//! Returns whether the system has a root instance assigned.
|
||||
//! @return True if a root prefab is assigned, false otherwise.
|
||||
virtual bool IsRootPrefabAssigned() const = 0;
|
||||
|
||||
//! Returns an optional reference to the root prefab instance.
|
||||
virtual Prefab::InstanceOptionalReference GetRootPrefabInstance() = 0;
|
||||
|
||||
//! Returns the template id for the root prefab instance.
|
||||
virtual Prefab::TemplateId GetRootPrefabTemplateId() = 0;
|
||||
|
||||
virtual void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) = 0;
|
||||
|
||||
//! Creates a prefab instance with the provided entities and nestedPrefabInstances.
|
||||
//! /param entities The entities to put under the new prefab.
|
||||
//! /param nestedPrefabInstances The nested prefab instances to put under the new prefab.
|
||||
//! /param filePath The filepath corresponding to the prefab file to be created.
|
||||
//! /param instanceToParentUnder The instance the newly created prefab instance is parented under.
|
||||
//! /return The optional reference to the prefab created.
|
||||
//! @param entities The entities to put under the new prefab.
|
||||
//! @param nestedPrefabInstances The nested prefab instances to put under the new prefab.
|
||||
//! @param filePath The filepath corresponding to the prefab file to be created.
|
||||
//! @param instanceToParentUnder The instance the newly created prefab instance is parented under.
|
||||
//! @return The optional reference to the prefab created.
|
||||
virtual Prefab::InstanceOptionalReference CreatePrefab(
|
||||
const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Prefab::Instance>>&& nestedPrefabInstances,
|
||||
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder = AZStd::nullopt) = 0;
|
||||
|
||||
//! Instantiate the prefab file provided.
|
||||
//! /param filePath The filepath for the prefab file the instance should be created from.
|
||||
//! /param instanceToParentUnder The instance the newly instantiated prefab instance is parented under.
|
||||
//! /return The optional reference to the prefab instance.
|
||||
//! @param filePath The filepath for the prefab file the instance should be created from.
|
||||
//! @param instanceToParentUnder The instance the newly instantiated prefab instance is parented under.
|
||||
//! @return The optional reference to the prefab instance.
|
||||
virtual Prefab::InstanceOptionalReference InstantiatePrefab(
|
||||
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder = AZStd::nullopt) = 0;
|
||||
|
||||
virtual Prefab::InstanceOptionalReference GetRootPrefabInstance() = 0;
|
||||
|
||||
virtual Prefab::TemplateId GetRootPrefabTemplateId() = 0;
|
||||
virtual void StartPlayInEditor() = 0;
|
||||
virtual void StopPlayInEditor() = 0;
|
||||
|
||||
//! Get all Assets generated by Prefab processing when entering Play-In Editor mode (Ctrl+G)
|
||||
//! /return The vector of Assets generated by Prefab processing
|
||||
//! @return The vector of Assets generated by Prefab processing
|
||||
virtual const Prefab::PrefabConversionUtils::InMemorySpawnableAssetContainer::SpawnableAssets& GetPlayInEditorAssetData() const = 0;
|
||||
|
||||
virtual bool LoadFromStream(AZ::IO::GenericStream& stream, AZStd::string_view filename) = 0;
|
||||
virtual bool SaveToStream(AZ::IO::GenericStream& stream, AZStd::string_view filename) = 0;
|
||||
|
||||
virtual void StartPlayInEditor() = 0;
|
||||
virtual void StopPlayInEditor() = 0;
|
||||
|
||||
virtual void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) = 0;
|
||||
//! Returns the reference to the instance corresponding to the RootAliasPath provided.
|
||||
//! @param rootAliasPath The RootAliasPath to be queried.
|
||||
//! @return A reference to the instance if valid, AZStd::nullopt otherwise.
|
||||
virtual Prefab::InstanceOptionalReference GetInstanceReferenceFromRootAliasPath(Prefab::RootAliasPath rootAliasPath) const = 0;
|
||||
|
||||
virtual bool IsRootPrefabAssigned() const = 0;
|
||||
//! Allows to iterate through all instances referenced in the path, from the root down.
|
||||
//! @param rootAliasPath The RootAliasPath to iterate through. If invalid, callback will not be called.
|
||||
//! @param callback The function to call on each instance. If it returns true, it prevents the rest of the path from being called.
|
||||
//! @return True if the iteration was halted by a callback returning true, false otherwise. Also returns false if the path is invalid.
|
||||
virtual bool GetInstancesInRootAliasPath(
|
||||
Prefab::RootAliasPath rootAliasPath, const AZStd::function<bool(const Prefab::InstanceOptionalReference)>& callback) const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
+64
@@ -510,6 +510,70 @@ namespace AzToolsFramework
|
||||
m_playInEditorData.m_isEnabled = false;
|
||||
}
|
||||
|
||||
bool PrefabEditorEntityOwnershipService::IsValidRootAliasPath(Prefab::RootAliasPath rootAliasPath) const
|
||||
{
|
||||
return GetInstanceReferenceFromRootAliasPath(rootAliasPath) != AZStd::nullopt;
|
||||
}
|
||||
|
||||
Prefab::InstanceOptionalReference PrefabEditorEntityOwnershipService::GetInstanceReferenceFromRootAliasPath(
|
||||
Prefab::RootAliasPath rootAliasPath) const
|
||||
{
|
||||
Prefab::InstanceOptionalReference instance = *m_rootInstance;
|
||||
|
||||
for (const auto& pathElement : rootAliasPath)
|
||||
{
|
||||
if (pathElement.Native() == rootAliasPath.begin()->Native())
|
||||
{
|
||||
// If the root is not the root Instance, the rootAliasPath is invalid.
|
||||
if (pathElement.Native() != instance->get().GetInstanceAlias())
|
||||
{
|
||||
return Prefab::InstanceOptionalReference();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the instance alias can't be found, the rootAliasPath is invalid.
|
||||
instance = instance->get().FindNestedInstance(pathElement.Native());
|
||||
if (!instance.has_value())
|
||||
{
|
||||
return Prefab::InstanceOptionalReference();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool PrefabEditorEntityOwnershipService::GetInstancesInRootAliasPath(
|
||||
Prefab::RootAliasPath rootAliasPath, const AZStd::function<bool(const Prefab::InstanceOptionalReference)>& callback) const
|
||||
{
|
||||
if (!IsValidRootAliasPath(rootAliasPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Prefab::InstanceOptionalReference instance;
|
||||
|
||||
for (const auto& pathElement : rootAliasPath)
|
||||
{
|
||||
if (!instance.has_value())
|
||||
{
|
||||
instance = *m_rootInstance;
|
||||
}
|
||||
else
|
||||
{
|
||||
instance = instance->get().FindNestedInstance(pathElement.Native());
|
||||
}
|
||||
|
||||
if(callback(instance))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Slice Buses implementation with Assert(false), this will exist only during Slice->Prefab
|
||||
// development to pinpoint and replace specific calls to Slice system
|
||||
|
||||
+6
@@ -169,11 +169,17 @@ namespace AzToolsFramework
|
||||
void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) override;
|
||||
bool IsRootPrefabAssigned() const override;
|
||||
|
||||
Prefab::InstanceOptionalReference GetInstanceReferenceFromRootAliasPath(Prefab::RootAliasPath rootAliasPath) const override;
|
||||
bool GetInstancesInRootAliasPath(
|
||||
Prefab::RootAliasPath rootAliasPath, const AZStd::function<bool(const Prefab::InstanceOptionalReference)>& callback) const override;
|
||||
|
||||
protected:
|
||||
|
||||
AZ::SliceComponent::SliceInstanceAddress GetOwningSlice() override;
|
||||
|
||||
private:
|
||||
bool IsValidRootAliasPath(Prefab::RootAliasPath rootAliasPath) const;
|
||||
|
||||
struct PlayInEditorData
|
||||
{
|
||||
AzToolsFramework::Prefab::PrefabConversionUtils::InMemorySpawnableAssetContainer m_assetsCache;
|
||||
|
||||
@@ -177,7 +177,6 @@ namespace AzToolsFramework
|
||||
AZStd::pair<Instance*, AZ::EntityId> GetInstanceAndEntityIdFromAliasPath(AliasPathView relativeAliasPath);
|
||||
AZStd::pair<const Instance*, AZ::EntityId> GetInstanceAndEntityIdFromAliasPath(AliasPathView relativeAliasPath) const;
|
||||
|
||||
|
||||
/**
|
||||
* Gets the aliases of all the nested instances, which are sourced by the template with the given id.
|
||||
*
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <AzToolsFramework/Commands/SelectionCommand.h>
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
|
||||
#include <AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
|
||||
@@ -97,9 +96,9 @@ namespace AzToolsFramework::Prefab
|
||||
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::SetSelectedEntities, selectedEntities);
|
||||
}
|
||||
|
||||
// Edit Prefab
|
||||
// Add undo element
|
||||
{
|
||||
auto editUndo = aznew PrefabFocusUndo("Edit Prefab");
|
||||
auto editUndo = aznew PrefabFocusUndo("Focus Prefab");
|
||||
editUndo->Capture(entityId);
|
||||
editUndo->SetParent(undoBatch.GetUndoBatch());
|
||||
FocusOnPrefabInstanceOwningEntityId(entityId);
|
||||
@@ -112,15 +111,24 @@ namespace AzToolsFramework::Prefab
|
||||
[[maybe_unused]] AzFramework::EntityContextId entityContextId)
|
||||
{
|
||||
// If only one instance is in the hierarchy, this operation is invalid
|
||||
size_t hierarchySize = m_instanceFocusHierarchy.size();
|
||||
if (hierarchySize <= 1)
|
||||
if (m_rootAliasFocusPathLength <= 1)
|
||||
{
|
||||
return AZ::Failure(
|
||||
AZStd::string("Prefab Focus Handler: Could not complete FocusOnParentOfFocusedPrefab operation while focusing on the root."));
|
||||
return AZ::Failure(AZStd::string(
|
||||
"Prefab Focus Handler: Could not complete FocusOnParentOfFocusedPrefab operation while focusing on the root."));
|
||||
}
|
||||
|
||||
RootAliasPath parentPath = m_rootAliasFocusPath;
|
||||
parentPath.RemoveFilename();
|
||||
|
||||
// Retrieve parent of currently focused prefab.
|
||||
InstanceOptionalReference parentInstance = GetReferenceFromContainerEntityId(m_instanceFocusHierarchy[hierarchySize - 2]);
|
||||
InstanceOptionalReference parentInstance = GetInstanceReference(parentPath);
|
||||
|
||||
// If only one instance is in the hierarchy, this operation is invalid
|
||||
if (!parentInstance.has_value())
|
||||
{
|
||||
return AZ::Failure(AZStd::string(
|
||||
"Prefab Focus Handler: Could not retrieve parent of current focus in FocusOnParentOfFocusedPrefab."));
|
||||
}
|
||||
|
||||
// Use container entity of parent Instance for focus operations.
|
||||
AZ::EntityId entityId = parentInstance->get().GetContainerEntityId();
|
||||
@@ -136,9 +144,9 @@ namespace AzToolsFramework::Prefab
|
||||
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::SetSelectedEntities, selectedEntities);
|
||||
}
|
||||
|
||||
// Edit Prefab
|
||||
// Add undo element
|
||||
{
|
||||
auto editUndo = aznew PrefabFocusUndo("Edit Prefab");
|
||||
auto editUndo = aznew PrefabFocusUndo("Focus Prefab");
|
||||
editUndo->Capture(entityId);
|
||||
editUndo->SetParent(undoBatch.GetUndoBatch());
|
||||
FocusOnPrefabInstanceOwningEntityId(entityId);
|
||||
@@ -149,12 +157,31 @@ namespace AzToolsFramework::Prefab
|
||||
|
||||
PrefabFocusOperationResult PrefabFocusHandler::FocusOnPathIndex([[maybe_unused]] AzFramework::EntityContextId entityContextId, int index)
|
||||
{
|
||||
if (index < 0 || index >= m_instanceFocusHierarchy.size())
|
||||
if (index < 0 || index >= m_rootAliasFocusPathLength)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Prefab Focus Handler: Invalid index on FocusOnPathIndex."));
|
||||
}
|
||||
|
||||
InstanceOptionalReference focusedInstance = GetReferenceFromContainerEntityId(m_instanceFocusHierarchy[index]);
|
||||
int i = 0;
|
||||
RootAliasPath indexedPath;
|
||||
for (const auto& pathElement : m_rootAliasFocusPath)
|
||||
{
|
||||
indexedPath.Append(pathElement);
|
||||
|
||||
if (i == index)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
InstanceOptionalReference focusedInstance = GetInstanceReference(indexedPath);
|
||||
|
||||
if (!focusedInstance.has_value())
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("Prefab Focus Handler: Could not retrieve instance at index %i.", index));
|
||||
}
|
||||
|
||||
return FocusOnOwningPrefab(focusedInstance->get().GetContainerEntityId());
|
||||
}
|
||||
@@ -192,13 +219,14 @@ namespace AzToolsFramework::Prefab
|
||||
}
|
||||
|
||||
// Close all container entities in the old path.
|
||||
CloseInstanceContainers(m_instanceFocusHierarchy);
|
||||
SetInstanceContainersOpenState(m_rootAliasFocusPath, false);
|
||||
|
||||
AZ::EntityId previousContainerEntityId = m_focusedInstanceContainerEntityId;
|
||||
const RootAliasPath previousContainerRootAliasPath = m_rootAliasFocusPath;
|
||||
const InstanceOptionalReference previousFocusedInstance = GetInstanceReference(previousContainerRootAliasPath);
|
||||
|
||||
// Do not store the container for the root instance, use an invalid EntityId instead.
|
||||
m_focusedInstanceContainerEntityId = focusedInstance->get().GetParentInstance().has_value() ? focusedInstance->get().GetContainerEntityId() : AZ::EntityId();
|
||||
m_rootAliasFocusPath = focusedInstance->get().GetAbsoluteInstanceAliasPath();
|
||||
m_focusedTemplateId = focusedInstance->get().GetTemplateId();
|
||||
m_rootAliasFocusPathLength = aznumeric_cast<int>(AZStd::distance(m_rootAliasFocusPath.begin(), m_rootAliasFocusPath.end()));
|
||||
|
||||
// Focus on the descendants of the container entity in the Editor, if the interface is initialized.
|
||||
if (m_focusModeInterface)
|
||||
@@ -214,15 +242,22 @@ namespace AzToolsFramework::Prefab
|
||||
// Refresh the read-only cache, if the interface is initialized.
|
||||
if (m_readOnlyEntityQueryInterface)
|
||||
{
|
||||
m_readOnlyEntityQueryInterface->RefreshReadOnlyState({ previousContainerEntityId, m_focusedInstanceContainerEntityId });
|
||||
EntityIdList containerEntities;
|
||||
|
||||
if (previousFocusedInstance.has_value())
|
||||
{
|
||||
containerEntities.push_back(previousFocusedInstance->get().GetContainerEntityId());
|
||||
}
|
||||
containerEntities.push_back(focusedInstance->get().GetContainerEntityId());
|
||||
|
||||
m_readOnlyEntityQueryInterface->RefreshReadOnlyState(containerEntities);
|
||||
}
|
||||
|
||||
// Refresh path variables.
|
||||
RefreshInstanceFocusList();
|
||||
RefreshInstanceFocusPath();
|
||||
|
||||
// Open all container entities in the new path.
|
||||
OpenInstanceContainers(m_instanceFocusHierarchy);
|
||||
SetInstanceContainersOpenState(m_rootAliasFocusPath, true);
|
||||
|
||||
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
|
||||
|
||||
@@ -237,17 +272,12 @@ namespace AzToolsFramework::Prefab
|
||||
InstanceOptionalReference PrefabFocusHandler::GetFocusedPrefabInstance(
|
||||
[[maybe_unused]] AzFramework::EntityContextId entityContextId) const
|
||||
{
|
||||
return GetReferenceFromContainerEntityId(m_focusedInstanceContainerEntityId);
|
||||
return GetInstanceReference(m_rootAliasFocusPath);
|
||||
}
|
||||
|
||||
AZ::EntityId PrefabFocusHandler::GetFocusedPrefabContainerEntityId([[maybe_unused]] AzFramework::EntityContextId entityContextId) const
|
||||
{
|
||||
if (m_focusedInstanceContainerEntityId.IsValid())
|
||||
{
|
||||
return m_focusedInstanceContainerEntityId;
|
||||
}
|
||||
|
||||
if (auto instance = GetReferenceFromContainerEntityId(m_focusedInstanceContainerEntityId); instance.has_value())
|
||||
if (const InstanceOptionalReference instance = GetInstanceReference(m_rootAliasFocusPath); instance.has_value())
|
||||
{
|
||||
return instance->get().GetContainerEntityId();
|
||||
}
|
||||
@@ -262,19 +292,13 @@ namespace AzToolsFramework::Prefab
|
||||
return false;
|
||||
}
|
||||
|
||||
InstanceOptionalReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
const InstanceOptionalConstReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
if (!instance.has_value())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this is owned by the root instance, that corresponds to an invalid m_focusedInstanceContainerEntityId.
|
||||
if (!instance->get().GetParentInstance().has_value())
|
||||
{
|
||||
return !m_focusedInstanceContainerEntityId.IsValid();
|
||||
}
|
||||
|
||||
return (instance->get().GetContainerEntityId() == m_focusedInstanceContainerEntityId);
|
||||
return (instance->get().GetAbsoluteInstanceAliasPath() == m_rootAliasFocusPath);
|
||||
}
|
||||
|
||||
bool PrefabFocusHandler::IsOwningPrefabInFocusHierarchy(AZ::EntityId entityId) const
|
||||
@@ -284,18 +308,10 @@ namespace AzToolsFramework::Prefab
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the focus is on the root, m_focusedInstanceContainerEntityId will be the invalid id.
|
||||
// In those case all entities are in the focus hierarchy and should return true.
|
||||
if (!m_focusedInstanceContainerEntityId.IsValid())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
InstanceOptionalReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
|
||||
InstanceOptionalConstReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
while (instance.has_value())
|
||||
{
|
||||
if (instance->get().GetContainerEntityId() == m_focusedInstanceContainerEntityId)
|
||||
if (instance->get().GetAbsoluteInstanceAliasPath() == m_rootAliasFocusPath)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -308,40 +324,47 @@ namespace AzToolsFramework::Prefab
|
||||
|
||||
const AZ::IO::Path& PrefabFocusHandler::GetPrefabFocusPath([[maybe_unused]] AzFramework::EntityContextId entityContextId) const
|
||||
{
|
||||
return m_instanceFocusPath;
|
||||
return m_filenameFocusPath;
|
||||
}
|
||||
|
||||
const int PrefabFocusHandler::GetPrefabFocusPathLength([[maybe_unused]] AzFramework::EntityContextId entityContextId) const
|
||||
{
|
||||
return aznumeric_cast<int>(m_instanceFocusHierarchy.size());
|
||||
return m_rootAliasFocusPathLength;
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::OnContextReset()
|
||||
{
|
||||
// Clear the old focus vector
|
||||
m_instanceFocusHierarchy.clear();
|
||||
|
||||
// Focus on the root prefab (AZ::EntityId() will default to it)
|
||||
FocusOnPrefabInstanceOwningEntityId(AZ::EntityId());
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::OnEntityInfoUpdatedName(AZ::EntityId entityId, [[maybe_unused]]const AZStd::string& name)
|
||||
{
|
||||
// Determine if the entityId is the container for any of the instances in the vector.
|
||||
auto result = AZStd::find_if(
|
||||
m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end(),
|
||||
[&, entityId](const AZ::EntityId& containerEntityId)
|
||||
{
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
return (instance->get().GetContainerEntityId() == entityId);
|
||||
}
|
||||
);
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
|
||||
if (result != m_instanceFocusHierarchy.end())
|
||||
if (prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
// Refresh the path and notify changes.
|
||||
RefreshInstanceFocusPath();
|
||||
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
|
||||
// Determine if the entityId is the container for any of the instances in the vector.
|
||||
bool match = prefabEditorEntityOwnershipInterface->GetInstancesInRootAliasPath(
|
||||
m_rootAliasFocusPath,
|
||||
[&](const Prefab::InstanceOptionalReference instance)
|
||||
{
|
||||
if (instance->get().GetContainerEntityId() == entityId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
if (match)
|
||||
{
|
||||
// Refresh the path and notify changes.
|
||||
RefreshInstanceFocusPath();
|
||||
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,108 +377,81 @@ namespace AzToolsFramework::Prefab
|
||||
|
||||
void PrefabFocusHandler::OnPrefabTemplateDirtyFlagUpdated(TemplateId templateId, [[maybe_unused]] bool status)
|
||||
{
|
||||
// Determine if the templateId matches any of the instances in the vector.
|
||||
auto result = AZStd::find_if(
|
||||
m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end(),
|
||||
[&, templateId](const AZ::EntityId& containerEntityId)
|
||||
{
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
return (instance->get().GetTemplateId() == templateId);
|
||||
}
|
||||
);
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
|
||||
if (result != m_instanceFocusHierarchy.end())
|
||||
if (prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
// Refresh the path and notify changes.
|
||||
RefreshInstanceFocusPath();
|
||||
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
|
||||
}
|
||||
}
|
||||
// Determine if the templateId matches any of the instances in the vector.
|
||||
bool match = prefabEditorEntityOwnershipInterface->GetInstancesInRootAliasPath(
|
||||
m_rootAliasFocusPath,
|
||||
[&](const Prefab::InstanceOptionalReference instance)
|
||||
{
|
||||
if (instance->get().GetTemplateId() == templateId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::RefreshInstanceFocusList()
|
||||
{
|
||||
m_instanceFocusHierarchy.clear();
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
AZStd::list<InstanceOptionalReference> instanceFocusList;
|
||||
|
||||
InstanceOptionalReference currentInstance = GetReferenceFromContainerEntityId(m_focusedInstanceContainerEntityId);
|
||||
while (currentInstance.has_value())
|
||||
{
|
||||
if (currentInstance->get().GetParentInstance().has_value())
|
||||
if (match)
|
||||
{
|
||||
m_instanceFocusHierarchy.emplace_back(currentInstance->get().GetContainerEntityId());
|
||||
// Refresh the path and notify changes.
|
||||
RefreshInstanceFocusPath();
|
||||
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_instanceFocusHierarchy.emplace_back(AZ::EntityId());
|
||||
}
|
||||
|
||||
currentInstance = currentInstance->get().GetParentInstance();
|
||||
}
|
||||
|
||||
// Invert the vector, since we need the top instance to be at index 0.
|
||||
AZStd::reverse(m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end());
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::RefreshInstanceFocusPath()
|
||||
{
|
||||
auto prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
|
||||
|
||||
m_instanceFocusPath.clear();
|
||||
|
||||
size_t index = 0;
|
||||
size_t maxIndex = m_instanceFocusHierarchy.size() - 1;
|
||||
|
||||
for (const AZ::EntityId& containerEntityId : m_instanceFocusHierarchy)
|
||||
{
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
if (instance.has_value())
|
||||
{
|
||||
AZStd::string prefabName;
|
||||
|
||||
if (index < maxIndex)
|
||||
{
|
||||
// Get the filename without the extension (stem).
|
||||
prefabName = instance->get().GetTemplateSourcePath().Stem().Native();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the full filename.
|
||||
prefabName = instance->get().GetTemplateSourcePath().Filename().Native();
|
||||
}
|
||||
|
||||
if (prefabSystemComponentInterface->IsTemplateDirty(instance->get().GetTemplateId()))
|
||||
{
|
||||
prefabName += "*";
|
||||
}
|
||||
|
||||
m_instanceFocusPath.Append(prefabName);
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::OpenInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const
|
||||
{
|
||||
// If this is called outside the Editor, this interface won't be initialized.
|
||||
if (!m_containerEntityInterface)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_filenameFocusPath.clear();
|
||||
|
||||
for (const AZ::EntityId& containerEntityId : instances)
|
||||
{
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
PrefabSystemComponentInterface* prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
|
||||
|
||||
if (instance.has_value())
|
||||
{
|
||||
m_containerEntityInterface->SetContainerOpen(instance->get().GetContainerEntityId(), true);
|
||||
}
|
||||
if (prefabEditorEntityOwnershipInterface && prefabSystemComponentInterface)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
prefabEditorEntityOwnershipInterface->GetInstancesInRootAliasPath(
|
||||
m_rootAliasFocusPath,
|
||||
[&](const Prefab::InstanceOptionalReference instance)
|
||||
{
|
||||
if (instance.has_value())
|
||||
{
|
||||
AZStd::string prefabName;
|
||||
|
||||
if (i == m_rootAliasFocusPathLength - 1)
|
||||
{
|
||||
// Get the full filename.
|
||||
prefabName = instance->get().GetTemplateSourcePath().Filename().Native();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the filename without the extension (stem).
|
||||
prefabName = instance->get().GetTemplateSourcePath().Stem().Native();
|
||||
}
|
||||
|
||||
if (prefabSystemComponentInterface->IsTemplateDirty(instance->get().GetTemplateId()))
|
||||
{
|
||||
prefabName += "*";
|
||||
}
|
||||
|
||||
m_filenameFocusPath.Append(prefabName);
|
||||
}
|
||||
|
||||
++i;
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabFocusHandler::CloseInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const
|
||||
void PrefabFocusHandler::SetInstanceContainersOpenState(const RootAliasPath& rootAliasPath, bool openState) const
|
||||
{
|
||||
// If this is called outside the Editor, this interface won't be initialized.
|
||||
if (!m_containerEntityInterface)
|
||||
@@ -463,33 +459,34 @@ namespace AzToolsFramework::Prefab
|
||||
return;
|
||||
}
|
||||
|
||||
for (const AZ::EntityId& containerEntityId : instances)
|
||||
{
|
||||
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
|
||||
if (instance.has_value())
|
||||
{
|
||||
m_containerEntityInterface->SetContainerOpen(instance->get().GetContainerEntityId(), false);
|
||||
}
|
||||
if (prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
prefabEditorEntityOwnershipInterface->GetInstancesInRootAliasPath(
|
||||
rootAliasPath,
|
||||
[&](const Prefab::InstanceOptionalReference instance)
|
||||
{
|
||||
m_containerEntityInterface->SetContainerOpen(instance->get().GetContainerEntityId(), openState);
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
InstanceOptionalReference PrefabFocusHandler::GetReferenceFromContainerEntityId(AZ::EntityId containerEntityId) const
|
||||
InstanceOptionalReference PrefabFocusHandler::GetInstanceReference(RootAliasPath rootAliasPath) const
|
||||
{
|
||||
if (!containerEntityId.IsValid())
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
|
||||
if (prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
|
||||
if (!prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
return prefabEditorEntityOwnershipInterface->GetRootPrefabInstance();
|
||||
return prefabEditorEntityOwnershipInterface->GetInstanceReferenceFromRootAliasPath(rootAliasPath);
|
||||
}
|
||||
|
||||
return m_instanceEntityMapperInterface->FindOwningInstance(containerEntityId);
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
} // namespace AzToolsFramework::Prefab
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
|
||||
#include <AzToolsFramework/FocusMode/FocusModeInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
|
||||
@@ -28,6 +29,7 @@ namespace AzToolsFramework
|
||||
namespace AzToolsFramework::Prefab
|
||||
{
|
||||
class InstanceEntityMapperInterface;
|
||||
class PrefabSystemComponentInterface;
|
||||
|
||||
//! Handles Prefab Focus mode, determining which prefab file entity changes will target.
|
||||
class PrefabFocusHandler final
|
||||
@@ -73,23 +75,20 @@ namespace AzToolsFramework::Prefab
|
||||
|
||||
private:
|
||||
PrefabFocusOperationResult FocusOnPrefabInstance(InstanceOptionalReference focusedInstance);
|
||||
void RefreshInstanceFocusList();
|
||||
void RefreshInstanceFocusPath();
|
||||
|
||||
void OpenInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const;
|
||||
void CloseInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const;
|
||||
void SetInstanceContainersOpenState(const RootAliasPath& rootAliasPath, bool openState) const;
|
||||
|
||||
InstanceOptionalReference GetReferenceFromContainerEntityId(AZ::EntityId containerEntityId) const;
|
||||
InstanceOptionalReference GetInstanceReference(RootAliasPath rootAliasPath) const;
|
||||
|
||||
//! The EntityId of the prefab container entity for the instance the editor is currently focusing on.
|
||||
AZ::EntityId m_focusedInstanceContainerEntityId = AZ::EntityId();
|
||||
//! The alias path for the instance the editor is currently focusing on, starting from the root instance.
|
||||
RootAliasPath m_rootAliasFocusPath = RootAliasPath();
|
||||
//! The templateId of the focused instance.
|
||||
TemplateId m_focusedTemplateId;
|
||||
//! The list of instances going from the root (index 0) to the focused instance,
|
||||
//! referenced by their prefab container's EntityId.
|
||||
AZStd::vector<AZ::EntityId> m_instanceFocusHierarchy;
|
||||
//! A path containing the filenames of the instances in the focus hierarchy, separated with a /.
|
||||
AZ::IO::Path m_instanceFocusPath;
|
||||
AZ::IO::Path m_filenameFocusPath;
|
||||
//! The length of the current focus path. Stored to simplify internal checks.
|
||||
int m_rootAliasFocusPathLength = 0;
|
||||
|
||||
ContainerEntityInterface* m_containerEntityInterface = nullptr;
|
||||
FocusModeInterface* m_focusModeInterface = nullptr;
|
||||
|
||||
@@ -815,7 +815,8 @@ namespace AzToolsFramework
|
||||
|
||||
if (templateRef.has_value())
|
||||
{
|
||||
return templateRef->get().IsDirty();
|
||||
return !templateRef->get().IsProcedural() && // all procedural prefabs are read-only
|
||||
templateRef->get().IsDirty();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -349,7 +349,7 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
StatementPrototype stmt("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=:1;");
|
||||
StatementPrototype stmt("SELECT COUNT(*) FROM sqlite_schema WHERE type='table' AND name=:1;");
|
||||
Statement* execute = stmt.Prepare(m_db); // execute now belongs to stmt and will die when stmt leaves scope.
|
||||
if (!execute->Prepared())
|
||||
{
|
||||
@@ -501,7 +501,7 @@ namespace AzToolsFramework
|
||||
// https://www.sqlite.org/c3ref/prepare.html ^^^^^^^^^
|
||||
|
||||
int res = sqlite3_prepare_v2(db, m_parentPrototype->GetSqlText().c_str(), (int)m_parentPrototype->GetSqlText().length() + 1, &m_statement, NULL);
|
||||
|
||||
|
||||
AZ_Assert(res == SQLITE_OK, "Statement::PrepareFirstTime: failed! %s ( prototype is '%s'). Error code returned is %d.", sqlite3_errmsg(db), m_parentPrototype->GetSqlText().c_str(), res);
|
||||
return ((res == SQLITE_OK)&&(m_statement));
|
||||
}
|
||||
@@ -703,7 +703,7 @@ namespace AzToolsFramework
|
||||
int res = sqlite3_clear_bindings(m_statement);
|
||||
AZ_Assert(res == SQLITE_OK, "Statement::sqlite3_clear_bindings: failed!");
|
||||
return (res == SQLITE_OK);
|
||||
|
||||
|
||||
}
|
||||
|
||||
int Statement::GetNamedParamIdx(const char* name)
|
||||
|
||||
+1
@@ -783,6 +783,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
EBUS_EVENT(ToolsApplicationEvents::Bus, InvalidatePropertyDisplay, Refresh_EntireTree);
|
||||
ToolsApplicationRequests::Bus::Broadcast(&ToolsApplicationRequests::Bus::Events::AddDirtyEntity, GetEntityId());
|
||||
}
|
||||
|
||||
void ScriptEditorComponent::LoadProperties()
|
||||
|
||||
@@ -41,6 +41,11 @@ namespace UnitTest
|
||||
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded,
|
||||
AzToolsFramework::EntityList{ m_entityMap[Passenger1EntityName], m_entityMap[Passenger2EntityName], m_entityMap[CityEntityName] });
|
||||
|
||||
// Initialize Prefab EOS Interface
|
||||
AzToolsFramework::PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
|
||||
AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
|
||||
ASSERT_TRUE(prefabEditorEntityOwnershipInterface);
|
||||
|
||||
// Create a car prefab from the passenger1 entity. The container entity will be created as part of the process.
|
||||
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> carInstance =
|
||||
m_prefabSystemComponent->CreatePrefab({ m_entityMap[Passenger1EntityName] }, {}, "test/car");
|
||||
@@ -59,11 +64,14 @@ namespace UnitTest
|
||||
ASSERT_TRUE(streetInstance);
|
||||
m_instanceMap[StreetEntityName] = streetInstance.get();
|
||||
|
||||
// Create a city prefab that nests the street instances created above and the city entity. The container entity will be created as part of the process.
|
||||
m_rootInstance =
|
||||
m_prefabSystemComponent->CreatePrefab({ m_entityMap[CityEntityName] }, MakeInstanceList(AZStd::move(streetInstance)), "test/city");
|
||||
ASSERT_TRUE(m_rootInstance);
|
||||
m_instanceMap[CityEntityName] = m_rootInstance.get();
|
||||
// Use the Prefab EOS root instance as the City instance. This will ensure functions that go through the EOS work in these tests too.
|
||||
m_rootInstance = prefabEditorEntityOwnershipInterface->GetRootPrefabInstance();
|
||||
ASSERT_TRUE(m_rootInstance.has_value());
|
||||
|
||||
m_rootInstance->get().AddEntity(*m_entityMap[CityEntityName]);
|
||||
m_rootInstance->get().AddInstance(AZStd::move(streetInstance));
|
||||
|
||||
m_instanceMap[CityEntityName] = &m_rootInstance->get();
|
||||
}
|
||||
|
||||
void SetUpEditorFixtureImpl() override
|
||||
@@ -84,7 +92,7 @@ namespace UnitTest
|
||||
|
||||
void TearDownEditorFixtureImpl() override
|
||||
{
|
||||
m_rootInstance.release();
|
||||
m_rootInstance->get().Reset();
|
||||
|
||||
PrefabTestFixture::TearDownEditorFixtureImpl();
|
||||
}
|
||||
@@ -92,7 +100,7 @@ namespace UnitTest
|
||||
AZStd::unordered_map<AZStd::string, AZ::Entity*> m_entityMap;
|
||||
AZStd::unordered_map<AZStd::string, Instance*> m_instanceMap;
|
||||
|
||||
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> m_rootInstance;
|
||||
InstanceOptionalReference m_rootInstance;
|
||||
|
||||
PrefabFocusInterface* m_prefabFocusInterface = nullptr;
|
||||
PrefabFocusPublicInterface* m_prefabFocusPublicInterface = nullptr;
|
||||
@@ -106,9 +114,7 @@ namespace UnitTest
|
||||
inline static const char* Passenger2EntityName = "Passenger2";
|
||||
};
|
||||
|
||||
// Test was disabled because the implementation of GetFocusedPrefabInstance now relies on the Prefab EOS,
|
||||
// which is not used by our test environment. This can be restored once Instance handles are implemented.
|
||||
TEST_F(PrefabFocusTests, DISABLED_PrefabFocus_FocusOnOwningPrefab_RootContainer)
|
||||
TEST_F(PrefabFocusTests, FocusOnOwningPrefabRootContainer)
|
||||
{
|
||||
// Verify FocusOnOwningPrefab works when passing the container entity of the root prefab.
|
||||
{
|
||||
@@ -123,9 +129,7 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
// Test was disabled because the implementation of GetFocusedPrefabInstance now relies on the Prefab EOS,
|
||||
// which is not used by our test environment. This can be restored once Instance handles are implemented.
|
||||
TEST_F(PrefabFocusTests, DISABLED_PrefabFocus_FocusOnOwningPrefab_RootEntity)
|
||||
TEST_F(PrefabFocusTests, FocusOnOwningPrefabRootEntity)
|
||||
{
|
||||
// Verify FocusOnOwningPrefab works when passing a nested entity of the root prefab.
|
||||
{
|
||||
@@ -140,7 +144,7 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PrefabFocusTests, PrefabFocus_FocusOnOwningPrefab_NestedContainer)
|
||||
TEST_F(PrefabFocusTests, FocusOnOwningPrefabNestedContainer)
|
||||
{
|
||||
// Verify FocusOnOwningPrefab works when passing the container entity of a nested prefab.
|
||||
{
|
||||
@@ -154,7 +158,7 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PrefabFocusTests, PrefabFocus_FocusOnOwningPrefab_NestedEntity)
|
||||
TEST_F(PrefabFocusTests, FocusOnOwningPrefabNestedEntity)
|
||||
{
|
||||
// Verify FocusOnOwningPrefab works when passing a nested entity of the a nested prefab.
|
||||
{
|
||||
@@ -168,7 +172,7 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PrefabFocusTests, PrefabFocus_FocusOnOwningPrefab_Clear)
|
||||
TEST_F(PrefabFocusTests, FocusOnOwningPrefabClear)
|
||||
{
|
||||
// Verify FocusOnOwningPrefab points to the root prefab when the focus is cleared.
|
||||
{
|
||||
@@ -188,7 +192,32 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PrefabFocusTests, PrefabFocus_IsOwningPrefabBeingFocused_Content)
|
||||
TEST_F(PrefabFocusTests, FocusOnParentOfFocusedPrefabLeaf)
|
||||
{
|
||||
// Call FocusOnParentOfFocusedPrefab on a leaf instance and verify the parent is focused correctly.
|
||||
{
|
||||
m_prefabFocusPublicInterface->FocusOnOwningPrefab(m_instanceMap[CarEntityName]->GetContainerEntityId());
|
||||
m_prefabFocusPublicInterface->FocusOnParentOfFocusedPrefab(m_editorEntityContextId);
|
||||
|
||||
EXPECT_EQ(
|
||||
&m_prefabFocusInterface->GetFocusedPrefabInstance(m_editorEntityContextId)->get(),
|
||||
m_instanceMap[StreetEntityName]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PrefabFocusTests, FocusOnParentOfFocusedPrefabRoot)
|
||||
{
|
||||
// Call FocusOnParentOfFocusedPrefab on the root instance and verify the operation fails.
|
||||
{
|
||||
m_prefabFocusPublicInterface->FocusOnOwningPrefab(m_instanceMap[CityEntityName]->GetContainerEntityId());
|
||||
auto outcome = m_prefabFocusPublicInterface->FocusOnParentOfFocusedPrefab(m_editorEntityContextId);
|
||||
|
||||
EXPECT_FALSE(outcome.IsSuccess());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PrefabFocusTests, IsOwningPrefabBeingFocusedContent)
|
||||
{
|
||||
// Verify IsOwningPrefabBeingFocused returns true for all entities in a focused prefab (container/nested)
|
||||
{
|
||||
@@ -199,7 +228,7 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PrefabFocusTests, PrefabFocus_IsOwningPrefabBeingFocused_AncestorsDescendants)
|
||||
TEST_F(PrefabFocusTests, IsOwningPrefabBeingFocusedAncestorsDescendants)
|
||||
{
|
||||
// Verify IsOwningPrefabBeingFocused returns false for all entities not in a focused prefab (ancestors/descendants)
|
||||
{
|
||||
@@ -213,7 +242,7 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PrefabFocusTests, PrefabFocus_IsOwningPrefabBeingFocused_Siblings)
|
||||
TEST_F(PrefabFocusTests, IsOwningPrefabBeingFocusedSiblings)
|
||||
{
|
||||
// Verify IsOwningPrefabBeingFocused returns false for all entities not in a focused prefab (siblings)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user