Merge pull request #5297 from aws-lumberyard-dev/nvsickle/FixEntityOrdering
Fix Entity Outliner sort order with Prefabs enabled
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include <AzCore/std/sort.h>
|
||||
#include <AzCore/RTTI/AttributeReader.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzToolsFramework/Commands/EntityStateCommand.h>
|
||||
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
@@ -468,6 +469,18 @@ namespace AzToolsFramework
|
||||
EntityIdList children;
|
||||
EditorEntityInfoRequestBus::EventResult(children, parentId, &EditorEntityInfoRequestBus::Events::GetChildren);
|
||||
|
||||
// If Prefabs are enabled, don't check the order for an invalid parent, just return its children (i.e. the root container entity)
|
||||
// There will currently always be one root container entity, so there's no order to retrieve
|
||||
if (!parentId.IsValid())
|
||||
{
|
||||
bool isPrefabEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(isPrefabEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
if (isPrefabEnabled)
|
||||
{
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
||||
EntityIdList entityChildOrder;
|
||||
AZ::EntityId sortEntityId = GetEntityIdForSortInfo(parentId);
|
||||
EditorEntitySortRequestBus::EventResult(entityChildOrder, sortEntityId, &EditorEntitySortRequestBus::Events::GetChildEntityOrderArray);
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/std/sort.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
|
||||
|
||||
static_assert(sizeof(AZ::u64) == sizeof(AZ::EntityId), "We use AZ::EntityId for Persistent ID, which is a u64 under the hood. These must be the same size otherwise the persistent id will have to be rewritten");
|
||||
|
||||
@@ -144,6 +146,12 @@ namespace AzToolsFramework
|
||||
bool EditorEntitySortComponent::AddChildEntityInternal(const AZ::EntityId& entityId, bool addToBack, EntityOrderArray::iterator insertPosition)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AzToolsFramework);
|
||||
|
||||
if (m_ignoreIncomingOrderChanges)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
auto entityItr = m_childEntityOrderCache.find(entityId);
|
||||
if (entityItr == m_childEntityOrderCache.end())
|
||||
{
|
||||
@@ -198,6 +206,12 @@ namespace AzToolsFramework
|
||||
bool EditorEntitySortComponent::RemoveChildEntity(const AZ::EntityId& entityId)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AzToolsFramework);
|
||||
|
||||
if (m_ignoreIncomingOrderChanges)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
auto entityItr = m_childEntityOrderCache.find(entityId);
|
||||
if (entityItr != m_childEntityOrderCache.end())
|
||||
{
|
||||
@@ -250,11 +264,30 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void EditorEntitySortComponent::OnPrefabInstancePropagationBegin()
|
||||
{
|
||||
m_ignoreIncomingOrderChanges = true;
|
||||
}
|
||||
|
||||
void EditorEntitySortComponent::OnPrefabInstancePropagationEnd()
|
||||
{
|
||||
m_ignoreIncomingOrderChanges = false;
|
||||
}
|
||||
|
||||
void EditorEntitySortComponent::MarkDirtyAndSendChangedEvent()
|
||||
{
|
||||
// mark the order as dirty before sending the ChildEntityOrderArrayUpdated event in order for PrepareSave to be properly handled in the case
|
||||
// one of the event listeners needs to build the InstanceDataHierarchy
|
||||
m_entityOrderIsDirty = true;
|
||||
|
||||
// Force an immediate update for prefabs, which won't receive PrepareSave
|
||||
bool isPrefabEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
isPrefabEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
if (isPrefabEnabled)
|
||||
{
|
||||
PrepareSave();
|
||||
}
|
||||
EditorEntitySortNotificationBus::Event(GetEntityId(), &EditorEntitySortNotificationBus::Events::ChildEntityOrderArrayUpdated);
|
||||
}
|
||||
|
||||
@@ -264,10 +297,20 @@ namespace AzToolsFramework
|
||||
// This is a special case for certain EditorComponents only!
|
||||
EditorEntitySortRequestBus::Handler::BusConnect(GetEntityId());
|
||||
EditorEntityContextNotificationBus::Handler::BusConnect();
|
||||
AzToolsFramework::Prefab::PrefabPublicNotificationBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void EditorEntitySortComponent::Activate()
|
||||
{
|
||||
// Run the post-serialize handler if prefabs are enabled because PostLoad won't be called automatically
|
||||
bool isPrefabEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
||||
isPrefabEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
if (isPrefabEnabled)
|
||||
{
|
||||
PostLoad();
|
||||
}
|
||||
|
||||
// Send out that the order for our entity is now updated
|
||||
EditorEntitySortNotificationBus::Event(GetEntityId(), &EditorEntitySortNotificationBus::Events::ChildEntityOrderArrayUpdated);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "EditorEntitySortBus.h"
|
||||
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicNotificationBus.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
@@ -20,6 +21,7 @@ namespace AzToolsFramework
|
||||
: public AzToolsFramework::Components::EditorComponentBase
|
||||
, public EditorEntitySortRequestBus::Handler
|
||||
, public EditorEntityContextNotificationBus::Handler
|
||||
, public AzToolsFramework::Prefab::PrefabPublicNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(EditorEntitySortComponent, "{6EA1E03D-68B2-466D-97F7-83998C8C27F0}", EditorComponentBase);
|
||||
@@ -45,6 +47,9 @@ namespace AzToolsFramework
|
||||
// EditorEntityContextNotificationBus::Handler
|
||||
void OnEntityStreamLoadSuccess() override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void OnPrefabInstancePropagationBegin() override;
|
||||
void OnPrefabInstancePropagationEnd() override;
|
||||
private:
|
||||
void MarkDirtyAndSendChangedEvent();
|
||||
bool AddChildEntityInternal(const AZ::EntityId& entityId, bool addToBack, EntityOrderArray::iterator insertPosition);
|
||||
@@ -106,6 +111,7 @@ namespace AzToolsFramework
|
||||
EntityOrderCache m_childEntityOrderCache; ///< The map of entity id to index for quick look up
|
||||
|
||||
bool m_entityOrderIsDirty = true; ///< This flag indicates our stored serialization order data is out of date and must be rebuilt before serialization occurs
|
||||
bool m_ignoreIncomingOrderChanges = false; ///< This is set when prefab propagation occurs so that non-authored order changes can be ignored
|
||||
};
|
||||
}
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -1144,6 +1144,10 @@ namespace AzToolsFramework
|
||||
|
||||
AZ::EntityId firstEntityIdToDelete = entityIdsNoFocusContainer[0];
|
||||
InstanceOptionalReference commonOwningInstance = GetOwnerInstanceByEntityId(firstEntityIdToDelete);
|
||||
if (!commonOwningInstance.has_value())
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Cannot delete entities belonging to an invalid instance"));
|
||||
}
|
||||
|
||||
// If the first entity id is a container entity id, then we need to mark its parent as the common owning instance because you
|
||||
// cannot delete an instance from itself.
|
||||
|
||||
Reference in New Issue
Block a user