merge from main
This commit is contained in:
@@ -341,6 +341,16 @@ namespace AZ
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->EBus<ComponentApplicationBus>("ComponentApplicationBus")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Category, "Components")
|
||||
|
||||
->Event("GetEntityName", &ComponentApplicationBus::Events::GetEntityName)
|
||||
->Event("SetEntityName", &ComponentApplicationBus::Events::SetEntityName);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -1050,6 +1060,20 @@ namespace AZ
|
||||
return AZStd::string();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// SetEntityName
|
||||
//=========================================================================
|
||||
bool ComponentApplication::SetEntityName(const EntityId& id, const AZStd::string_view name)
|
||||
{
|
||||
Entity* entity = FindEntity(id);
|
||||
if (entity)
|
||||
{
|
||||
entity->SetName(name);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// EnumerateEntities
|
||||
//=========================================================================
|
||||
|
||||
@@ -209,6 +209,7 @@ namespace AZ
|
||||
bool DeleteEntity(const EntityId& id) override;
|
||||
Entity* FindEntity(const EntityId& id) override;
|
||||
AZStd::string GetEntityName(const EntityId& id) override;
|
||||
bool SetEntityName(const EntityId& id, const AZStd::string_view name) override;
|
||||
void EnumerateEntities(const ComponentApplicationRequests::EntityCallback& callback) override;
|
||||
ComponentApplication* GetApplication() override { return this; }
|
||||
/// Returns the serialize context that has been registered with the app, if there is one.
|
||||
|
||||
@@ -130,7 +130,13 @@ namespace AZ
|
||||
//! @param entity A reference to the entity whose name you are seeking.
|
||||
//! @return The name of the entity with the specified entity ID.
|
||||
//! If no entity is found for the specified ID, it returns an empty string.
|
||||
virtual AZStd::string GetEntityName(const EntityId& id) { (void)id; return AZStd::string(); };
|
||||
virtual AZStd::string GetEntityName(const EntityId& id) { (void)id; return AZStd::string(); }
|
||||
|
||||
//! Sets the name of the entity that has the specified entity ID.
|
||||
//! Entity names are not enforced to be unique.
|
||||
//! @param entityId A reference to the entity whose name you want to change.
|
||||
//! @return True if the name was changed successfully, false if it wasn't.
|
||||
virtual bool SetEntityName([[maybe_unused]] const EntityId& id, [[maybe_unused]] const AZStd::string_view name) { return false; }
|
||||
|
||||
//! The type that AZ::ComponentApplicationRequests::EnumerateEntities uses to
|
||||
//! pass entity callbacks to the application for enumeration.
|
||||
|
||||
@@ -258,7 +258,8 @@ namespace AZ
|
||||
Method("CreateFromMatrix3x3", &Quaternion::CreateFromMatrix3x3)->
|
||||
Method("CreateFromMatrix4x4", &Quaternion::CreateFromMatrix4x4)->
|
||||
Method("CreateFromAxisAngle", &Quaternion::CreateFromAxisAngle)->
|
||||
Method("CreateShortestArc", &Quaternion::CreateShortestArc)
|
||||
Method("CreateShortestArc", &Quaternion::CreateShortestArc)->
|
||||
Method("CreateFromEulerAnglesDegrees", &Quaternion::CreateFromEulerAnglesDegrees)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,6 +250,7 @@ namespace AZ
|
||||
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
|
||||
Attribute(Script::Attributes::Storage, Script::Attributes::StorageType::Value)->
|
||||
Attribute(Script::Attributes::GenericConstructorOverride, &Internal::TransformDefaultConstructor)->
|
||||
Constructor<const Vector3&, const Quaternion&, const Vector3&>()->
|
||||
Method("GetBasis", &Transform::GetBasis)->
|
||||
Method("GetBasisX", &Transform::GetBasisX)->
|
||||
Method("GetBasisY", &Transform::GetBasisY)->
|
||||
|
||||
@@ -40,14 +40,13 @@ ly_add_target(
|
||||
${common_dir}
|
||||
${AZ_CORE_RADTELEMETRY_INCLUDE_DIRECTORIES}
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
3rdParty::zlib
|
||||
3rdParty::zstd
|
||||
3rdParty::cityhash
|
||||
PUBLIC
|
||||
3rdParty::Lua
|
||||
3rdParty::RapidJSON
|
||||
3rdParty::RapidXML
|
||||
3rdParty::zlib
|
||||
3rdParty::zstd
|
||||
3rdParty::cityhash
|
||||
${AZ_CORE_RADTELEMETRY_BUILD_DEPENDENCIES}
|
||||
)
|
||||
ly_add_source_properties(
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Physics
|
||||
class CharacterColliderNodeConfiguration
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(CharacterColliderNodeConfiguration, "{C16F3301-0979-400C-B734-692D83755C39}");
|
||||
AZ_RTTI(Physics::CharacterColliderNodeConfiguration, "{C16F3301-0979-400C-B734-692D83755C39}");
|
||||
AZ_CLASS_ALLOCATOR_DECL
|
||||
|
||||
virtual ~CharacterColliderNodeConfiguration() = default;
|
||||
@@ -42,7 +42,7 @@ namespace Physics
|
||||
class CharacterColliderConfiguration
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(CharacterColliderConfiguration, "{4DFF1434-DF5B-4ED5-BE0F-D3E66F9B331A}");
|
||||
AZ_RTTI(Physics::CharacterColliderConfiguration, "{4DFF1434-DF5B-4ED5-BE0F-D3E66F9B331A}");
|
||||
AZ_CLASS_ALLOCATOR_DECL
|
||||
|
||||
virtual ~CharacterColliderConfiguration() = default;
|
||||
@@ -63,21 +63,23 @@ namespace Physics
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(CharacterConfiguration, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(CharacterConfiguration, "{58D5A6CA-113B-4AC3-8D53-239DB0C4E240}", AzPhysics::SimulatedBodyConfiguration);
|
||||
AZ_RTTI(Physics::CharacterConfiguration, "{58D5A6CA-113B-4AC3-8D53-239DB0C4E240}", AzPhysics::SimulatedBodyConfiguration);
|
||||
|
||||
virtual ~CharacterConfiguration() = default;
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
AzPhysics::CollisionGroups::Id m_collisionGroupId; ///< Which layers does this character collide with.
|
||||
AzPhysics::CollisionLayer m_collisionLayer; ///< Which collision layer is this character on.
|
||||
MaterialSelection m_materialSelection; ///< Material selected from library for the body associated with the character.
|
||||
AZ::Vector3 m_upDirection = AZ::Vector3::CreateAxisZ(); ///< Up direction for character orientation and step behavior.
|
||||
float m_maximumSlopeAngle = 30.0f; ///< The maximum slope on which the character can move, in degrees.
|
||||
float m_stepHeight = 0.5f; ///< Affects what size steps the character can climb.
|
||||
float m_minimumMovementDistance = 0.001f; ///< To avoid jittering, the controller will not attempt to move distances below this.
|
||||
float m_maximumSpeed = 100.0f; ///< If the accumulated requested velocity for a tick exceeds this magnitude, it will be clamped.
|
||||
AZStd::string m_colliderTag; ///< Used to identify the collider associated with the character controller.
|
||||
AzPhysics::CollisionGroups::Id m_collisionGroupId; //!< Which layers does this character collide with.
|
||||
AzPhysics::CollisionLayer m_collisionLayer; //!< Which collision layer is this character on.
|
||||
MaterialSelection m_materialSelection; //!< Material selected from library for the body associated with the character.
|
||||
AZ::Vector3 m_upDirection = AZ::Vector3::CreateAxisZ(); //!< Up direction for character orientation and step behavior.
|
||||
float m_maximumSlopeAngle = 30.0f; //!< The maximum slope on which the character can move, in degrees.
|
||||
float m_stepHeight = 0.5f; //!< Affects what size steps the character can climb.
|
||||
float m_minimumMovementDistance = 0.001f; //!< To avoid jittering, the controller will not attempt to move distances below this.
|
||||
float m_maximumSpeed = 100.0f; //!< If the accumulated requested velocity for a tick exceeds this magnitude, it will be clamped.
|
||||
AZStd::string m_colliderTag; //!< Used to identify the collider associated with the character controller.
|
||||
AZStd::shared_ptr<Physics::ShapeConfiguration> m_shapeConfig = nullptr; //!< The shape to use when creating the character controller.
|
||||
AZStd::vector<AZStd::shared_ptr<Physics::Shape>> m_colliders; //!< The list of colliders to attach to the character controller.
|
||||
};
|
||||
|
||||
/// Basic implementation of common character-style needs as a WorldBody. Is not a full-functional ship-ready
|
||||
@@ -88,7 +90,7 @@ namespace Physics
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(Character, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(Character, "{962E37A1-3401-4672-B896-0A6157CFAC97}", AzPhysics::SimulatedBody);
|
||||
AZ_RTTI(Physics::Character, "{962E37A1-3401-4672-B896-0A6157CFAC97}", AzPhysics::SimulatedBody);
|
||||
|
||||
~Character() override = default;
|
||||
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ namespace AzPhysics
|
||||
struct SimulatedBodyConfiguration
|
||||
{
|
||||
AZ_CLASS_ALLOCATOR_DECL;
|
||||
AZ_RTTI(SimulatedBodyConfiguration, "{52844E3D-79C8-4F34-AF63-5C45ADE77F85}");
|
||||
AZ_RTTI(AzPhysics::SimulatedBodyConfiguration, "{52844E3D-79C8-4F34-AF63-5C45ADE77F85}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
SimulatedBodyConfiguration() = default;
|
||||
|
||||
@@ -246,26 +246,6 @@ namespace Physics
|
||||
using SystemRequests = System;
|
||||
using SystemRequestBus = AZ::EBus<SystemRequests, SystemRequestsTraits>;
|
||||
|
||||
/// Physics character system global requests.
|
||||
class CharacterSystemRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
// EBusTraits
|
||||
// singleton pattern
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
|
||||
virtual ~CharacterSystemRequests() = default;
|
||||
|
||||
/// Creates the physics representation used to handle basic character interactions (also known as a character
|
||||
/// controller).
|
||||
virtual AZStd::unique_ptr<Character> CreateCharacter(const CharacterConfiguration& characterConfig,
|
||||
const ShapeConfiguration& shapeConfig, AzPhysics::SceneHandle& sceneHandle) = 0;
|
||||
};
|
||||
|
||||
typedef AZ::EBus<CharacterSystemRequests> CharacterSystemRequestBus;
|
||||
|
||||
/// Physics system global debug requests.
|
||||
class SystemDebugRequests
|
||||
: public AZ::EBusTraits
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace AzFramework
|
||||
|
||||
// ViewportControllerInterface ...
|
||||
bool HandleInputChannelEvent(const ViewportControllerInputEvent& event) override;
|
||||
void ResetInputChannels() override;
|
||||
void UpdateViewport(const ViewportControllerUpdateEvent& event) override;
|
||||
void RegisterViewportContext(ViewportId viewport) override;
|
||||
void UnregisterViewportContext(ViewportId viewport) override;
|
||||
@@ -58,6 +59,7 @@ namespace AzFramework
|
||||
ViewportId GetViewportId() const { return m_viewportId; }
|
||||
|
||||
virtual bool HandleInputChannelEvent([[maybe_unused]]const ViewportControllerInputEvent& event) { return false; }
|
||||
virtual void ResetInputChannels() {}
|
||||
virtual void UpdateViewport([[maybe_unused]]const ViewportControllerUpdateEvent& event) {}
|
||||
|
||||
private:
|
||||
|
||||
@@ -30,6 +30,15 @@ namespace AzFramework
|
||||
return instanceIt->second->HandleInputChannelEvent(event);
|
||||
}
|
||||
|
||||
template <class TViewportControllerInstance, ViewportControllerPriority Priority>
|
||||
void MultiViewportController<TViewportControllerInstance, Priority>::ResetInputChannels()
|
||||
{
|
||||
for (auto instanceIt = m_instances.begin(); instanceIt != m_instances.end(); ++instanceIt)
|
||||
{
|
||||
instanceIt->second->ResetInputChannels();
|
||||
}
|
||||
}
|
||||
|
||||
template <class TViewportControllerInstance, ViewportControllerPriority Priority>
|
||||
void MultiViewportController<TViewportControllerInstance, Priority>::UpdateViewport(const ViewportControllerUpdateEvent& event)
|
||||
{
|
||||
|
||||
@@ -49,6 +49,11 @@ namespace AzFramework
|
||||
|
||||
bool ViewportControllerList::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event)
|
||||
{
|
||||
if (!IsEnabled())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If our event priority is "custom", we should dispatch at all priority levels in order
|
||||
using AzFramework::ViewportControllerPriority;
|
||||
if (event.m_priority == AzFramework::ViewportControllerPriority::DispatchToAllPriorities)
|
||||
@@ -76,6 +81,23 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportControllerList::ResetInputChannels()
|
||||
{
|
||||
// We don't need to send this while we're disabled, we're guaranteed to call ResetInputChannels after being re-enabled.
|
||||
if (!IsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& controllerList : m_controllers)
|
||||
{
|
||||
for (const auto& controller : controllerList.second)
|
||||
{
|
||||
controller->ResetInputChannels();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ViewportControllerList::DispatchInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event)
|
||||
{
|
||||
if (auto priorityListIt = m_controllers.find(event.m_priority); priorityListIt != m_controllers.end())
|
||||
@@ -106,6 +128,11 @@ namespace AzFramework
|
||||
|
||||
void ViewportControllerList::UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event)
|
||||
{
|
||||
if (!IsEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If our event priority is "custom", we should dispatch at all priority levels in reverse order
|
||||
// Reverse order lets high priority controllers get the last say in viewport update operations
|
||||
using AzFramework::ViewportControllerPriority;
|
||||
@@ -174,4 +201,22 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ViewportControllerList::IsEnabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
void ViewportControllerList::SetEnabled(bool enabled)
|
||||
{
|
||||
if (m_enabled != enabled)
|
||||
{
|
||||
m_enabled = enabled;
|
||||
// If we've been re-enabled, reset our input channels as they may have missed state changes.
|
||||
if (m_enabled)
|
||||
{
|
||||
ResetInputChannels();
|
||||
}
|
||||
}
|
||||
}
|
||||
} //namespace AzFramework
|
||||
|
||||
@@ -37,6 +37,9 @@ namespace AzFramework
|
||||
//! either a controller returns true to consume the event in OnInputChannelEvent or the controller list is exhausted.
|
||||
//! InputChannelEvents are sent to controllers in priority order (from the lowest priority value to the highest).
|
||||
bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override;
|
||||
//! Dispatches a ResetInputChannels call to all controllers registered to this list.
|
||||
//! Calls to controllers are made in an undefined order.
|
||||
void ResetInputChannels() override;
|
||||
//! Dispatches an update tick to all controllers registered to this list.
|
||||
//! This occurs in *reverse* priority order (i.e. from the highest priority value to the lowest) so that
|
||||
//! controllers with the highest registration priority may override the transforms of the controllers with the
|
||||
@@ -50,6 +53,12 @@ namespace AzFramework
|
||||
//! All ViewportControllerLists have a priority of Custom to ensure
|
||||
//! that they receive events at all priorities from any parent controllers.
|
||||
AzFramework::ViewportControllerPriority GetPriority() const { return ViewportControllerPriority::DispatchToAllPriorities; }
|
||||
//! Returns true if this controller list is enabled, i.e.
|
||||
//! it is accepting and forwarding input and update events to its children.
|
||||
bool IsEnabled() const;
|
||||
//! Set this controller list's enabled state.
|
||||
//! If a controller list is disabled, it will ignore all input and update events rather than dispatching them to its children.
|
||||
void SetEnabled(bool enabled);
|
||||
|
||||
private:
|
||||
void SortControllers();
|
||||
@@ -58,5 +67,6 @@ namespace AzFramework
|
||||
|
||||
AZStd::unordered_map<AzFramework::ViewportControllerPriority, AZStd::vector<ViewportControllerPtr>> m_controllers;
|
||||
AZStd::unordered_set<ViewportId> m_viewports;
|
||||
bool m_enabled = true;
|
||||
};
|
||||
} //namespace AzFramework
|
||||
|
||||
@@ -33,12 +33,12 @@ ly_add_target(
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
AZ::AzCore
|
||||
PUBLIC
|
||||
AZ::GridMate
|
||||
3rdParty::md5
|
||||
3rdParty::zlib
|
||||
3rdParty::zstd
|
||||
3rdParty::lz4
|
||||
PUBLIC
|
||||
AZ::GridMate
|
||||
)
|
||||
|
||||
if(LY_ENABLE_STATISTICAL_PROFILING)
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <AzCore/std/typetraits/is_enum.h>
|
||||
#include <AzCore/RTTI/TypeInfo.h>
|
||||
#include <AzCore/RTTI/TypeSafeIntegral.h>
|
||||
#include <AzCore/Name/Name.h>
|
||||
#include <AzCore/Name/NameDictionary.h>
|
||||
|
||||
namespace AzNetworking
|
||||
{
|
||||
@@ -173,6 +175,22 @@ namespace AzNetworking
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct SerializeObjectHelper<AZ::Name>
|
||||
{
|
||||
static bool SerializeObject(ISerializer& serializer, AZ::Name& value)
|
||||
{
|
||||
AZ::Name::Hash nameHash = value.GetHash();
|
||||
bool result = serializer.Serialize(nameHash, "NameHash");
|
||||
|
||||
if (result && serializer.GetSerializerMode() == SerializerMode::WriteToObject)
|
||||
{
|
||||
value = AZ::NameDictionary::Instance().FindName(nameHash);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#include <AzNetworking/Serialization/AzContainerSerializers.h>
|
||||
|
||||
@@ -2298,6 +2298,12 @@ namespace AzQtComponents
|
||||
OptimizedSetParent(dock, mainWindow);
|
||||
mainWindow->addDockWidget(Qt::LeftDockWidgetArea, dock);
|
||||
dock->show();
|
||||
|
||||
// Make sure we listen for events on the dock widget being put into a floating dock window
|
||||
// because this might be called programmatically, so the dock widget might have never been
|
||||
// parented to our m_mainWindow initially, so it won't already have an event filter,
|
||||
// which will prevent the docking functionality from working.
|
||||
dock->installEventFilter(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -815,8 +815,6 @@ namespace AzToolsFramework
|
||||
/// Hide or show the circular dependency error when saving slices
|
||||
virtual void SetShowCircularDependencyError(const bool& /*showCircularDependencyError*/) {}
|
||||
|
||||
virtual void SetEditTool(const char* /*tool*/) {}
|
||||
|
||||
/// Launches the Lua editor and opens the specified (space separated) files.
|
||||
virtual void LaunchLuaEditor(const char* /*files*/) {}
|
||||
|
||||
|
||||
+8
-2
@@ -491,6 +491,14 @@ namespace AzToolsFramework
|
||||
|
||||
EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnStartPlayInEditorBegin);
|
||||
|
||||
//cache the current selected entities.
|
||||
ToolsApplicationRequests::Bus::BroadcastResult(m_selectedBeforeStartingGame, &ToolsApplicationRequests::GetSelectedEntities);
|
||||
//deselect entities if selected when entering game mode before deactivating the entities in StartPlayInEditor(...)
|
||||
if (!m_selectedBeforeStartingGame.empty())
|
||||
{
|
||||
ToolsApplicationRequests::Bus::Broadcast(&ToolsApplicationRequests::MarkEntitiesDeselected, m_selectedBeforeStartingGame);
|
||||
}
|
||||
|
||||
if (m_isLegacySliceService)
|
||||
{
|
||||
SliceEditorEntityOwnershipService* editorEntityOwnershipService =
|
||||
@@ -507,8 +515,6 @@ namespace AzToolsFramework
|
||||
|
||||
m_isRunningGame = true;
|
||||
|
||||
ToolsApplicationRequests::Bus::BroadcastResult(m_selectedBeforeStartingGame, &ToolsApplicationRequests::GetSelectedEntities);
|
||||
|
||||
EditorEntityContextNotificationBus::Broadcast(&EditorEntityContextNotification::OnStartPlayInEditor);
|
||||
}
|
||||
|
||||
|
||||
+20
-7
@@ -94,6 +94,7 @@ namespace AzToolsFramework
|
||||
m_prefabSystemComponent->RemoveTemplate(templateId);
|
||||
}
|
||||
m_rootInstance->Reset();
|
||||
m_rootInstance->SetContainerEntityName("Level");
|
||||
|
||||
AzFramework::EntityOwnershipServiceNotificationBus::Event(
|
||||
m_entityContextId, &AzFramework::EntityOwnershipServiceNotificationBus::Events::OnEntityOwnershipServiceReset);
|
||||
@@ -198,6 +199,7 @@ namespace AzToolsFramework
|
||||
|
||||
m_rootInstance->SetTemplateId(templateId);
|
||||
m_rootInstance->SetTemplateSourcePath(m_loaderInterface->GetRelativePathToProject(filename));
|
||||
m_rootInstance->SetContainerEntityName("Level");
|
||||
m_prefabSystemComponent->PropagateTemplateChanges(templateId);
|
||||
|
||||
return true;
|
||||
@@ -279,18 +281,29 @@ namespace AzToolsFramework
|
||||
AZStd::unique_ptr<Prefab::Instance> createdPrefabInstance =
|
||||
m_prefabSystemComponent->CreatePrefab(entities, AZStd::move(nestedPrefabInstances), filePath);
|
||||
|
||||
if (!instanceToParentUnder)
|
||||
{
|
||||
instanceToParentUnder = *m_rootInstance;
|
||||
}
|
||||
|
||||
if (createdPrefabInstance)
|
||||
{
|
||||
if (!instanceToParentUnder)
|
||||
{
|
||||
instanceToParentUnder = *m_rootInstance;
|
||||
}
|
||||
|
||||
Prefab::Instance& addedInstance = instanceToParentUnder->get().AddInstance(AZStd::move(createdPrefabInstance));
|
||||
HandleEntitiesAdded({addedInstance.m_containerEntity.get()});
|
||||
AZ::Entity* containerEntity = addedInstance.m_containerEntity.get();
|
||||
containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
|
||||
HandleEntitiesAdded({containerEntity});
|
||||
HandleEntitiesAdded(entities);
|
||||
|
||||
// Update the template of the instance since we modified the entities of the instance by calling HandleEntitiesAdded.
|
||||
Prefab::PrefabDom serializedInstance;
|
||||
if (Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(addedInstance, serializedInstance))
|
||||
{
|
||||
m_prefabSystemComponent->UpdatePrefabTemplate(addedInstance.GetTemplateId(), serializedInstance);
|
||||
}
|
||||
|
||||
return addedInstance;
|
||||
}
|
||||
HandleEntitiesAdded(entities);
|
||||
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -186,7 +186,7 @@ namespace AzToolsFramework
|
||||
PlayInEditorData m_playInEditorData;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PrefabSystemComponentInterface interface implementation
|
||||
// PrefabEditorEntityOwnershipInterface implementation
|
||||
Prefab::InstanceOptionalReference CreatePrefab(
|
||||
const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Prefab::Instance>>&& nestedPrefabInstances,
|
||||
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder) override;
|
||||
|
||||
@@ -123,7 +123,11 @@ namespace AzToolsFramework
|
||||
void Instance::SetTemplateSourcePath(AZ::IO::PathView sourcePath)
|
||||
{
|
||||
m_templateSourcePath = sourcePath;
|
||||
m_containerEntity->SetName(sourcePath.Filename().Native());
|
||||
}
|
||||
|
||||
void Instance::SetContainerEntityName(AZStd::string_view containerName)
|
||||
{
|
||||
m_containerEntity->SetName(containerName);
|
||||
}
|
||||
|
||||
bool Instance::AddEntity(AZ::Entity& entity)
|
||||
@@ -563,7 +567,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZ::EntityId Instance::GetContainerEntityId() const
|
||||
{
|
||||
return m_containerEntity->GetId();
|
||||
return m_containerEntity ? m_containerEntity->GetId() : AZ::EntityId();
|
||||
}
|
||||
|
||||
bool Instance::HasContainerEntity() const
|
||||
|
||||
@@ -80,6 +80,7 @@ namespace AzToolsFramework
|
||||
|
||||
const AZ::IO::Path& GetTemplateSourcePath() const;
|
||||
void SetTemplateSourcePath(AZ::IO::PathView sourcePath);
|
||||
void SetContainerEntityName(AZStd::string_view containerName);
|
||||
|
||||
bool AddEntity(AZ::Entity& entity);
|
||||
bool AddEntity(AZ::Entity& entity, EntityAlias entityAlias);
|
||||
|
||||
+25
-1
@@ -15,6 +15,7 @@
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/TemplateInstanceMapperInterface.h>
|
||||
@@ -116,10 +117,24 @@ namespace AzToolsFramework
|
||||
"Could not find Template using Id '%llu'. Unable to update Instance.",
|
||||
currentTemplateId);
|
||||
|
||||
// Remove the instance from update queue if its corresponding template couldn't be found
|
||||
isUpdateSuccessful = false;
|
||||
m_instancesUpdateQueue.pop();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
auto findInstancesResult = m_templateInstanceMapperInterface->FindInstancesOwnedByTemplate(instanceTemplateId)->get();
|
||||
|
||||
if (findInstancesResult.find(instanceToUpdate) == findInstancesResult.end())
|
||||
{
|
||||
// Since nested instances get reconstructed during propagation, remove any nested instance that no longer
|
||||
// maps to a template.
|
||||
isUpdateSuccessful = false;
|
||||
m_instancesUpdateQueue.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
Template& currentTemplate = currentTemplateReference->get();
|
||||
Instance::EntityList newEntities;
|
||||
if (PrefabDomUtils::LoadInstanceFromPrefabDom(*instanceToUpdate, newEntities, currentTemplate.GetPrefabDom()))
|
||||
@@ -139,9 +154,18 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
m_instancesUpdateQueue.pop();
|
||||
|
||||
}
|
||||
|
||||
for (auto entityIdIterator = selectedEntityIds.begin(); entityIdIterator != selectedEntityIds.end(); entityIdIterator++)
|
||||
{
|
||||
// Since entities get recreated during propagation, we need to check whether the entities correspoding to the list
|
||||
// of selected entity ids are present or not.
|
||||
AZ::Entity* entity = GetEntityById(*entityIdIterator);
|
||||
if (entity == nullptr)
|
||||
{
|
||||
selectedEntityIds.erase(entityIdIterator--);
|
||||
}
|
||||
}
|
||||
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, selectedEntityIds);
|
||||
|
||||
// Enable the Outliner
|
||||
|
||||
@@ -15,15 +15,16 @@
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Utils/TypeHash.h>
|
||||
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
|
||||
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/InstanceEntityIdMapper.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/InstanceToTemplateInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabLoaderInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabUndo.h>
|
||||
@@ -37,12 +38,14 @@ namespace AzToolsFramework
|
||||
void PrefabPublicHandler::RegisterPrefabPublicHandlerInterface()
|
||||
{
|
||||
m_instanceEntityMapperInterface = AZ::Interface<InstanceEntityMapperInterface>::Get();
|
||||
AZ_Assert(
|
||||
m_instanceEntityMapperInterface, "PrefabPublicHandler - Could not retrieve instance of InstanceEntityMapperInterface");
|
||||
AZ_Assert(m_instanceEntityMapperInterface, "PrefabPublicHandler - Could not retrieve instance of InstanceEntityMapperInterface");
|
||||
|
||||
m_instanceToTemplateInterface = AZ::Interface<InstanceToTemplateInterface>::Get();
|
||||
AZ_Assert(m_instanceToTemplateInterface, "PrefabPublicHandler - Could not retrieve instance of InstanceToTemplateInterface");
|
||||
|
||||
m_prefabLoaderInterface = AZ::Interface<PrefabLoaderInterface>::Get();
|
||||
AZ_Assert(m_prefabLoaderInterface, "Could not get PrefabLoaderInterface on PrefabPublicHandler construction.");
|
||||
|
||||
m_prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
|
||||
AZ_Assert(m_prefabSystemComponentInterface, "Could not get PrefabSystemComponentInterface on PrefabPublicHandler construction.");
|
||||
|
||||
@@ -59,91 +62,160 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath)
|
||||
{
|
||||
EntityList inputEntityList, topLevelEntities;
|
||||
AZ::EntityId commonRootEntityId;
|
||||
InstanceOptionalReference commonRootEntityOwningInstance;
|
||||
PrefabOperationResult findCommonRootOutcome = FindCommonRootOwningInstance(
|
||||
entityIds, inputEntityList, topLevelEntities, commonRootEntityId, commonRootEntityOwningInstance);
|
||||
if (!findCommonRootOutcome.IsSuccess())
|
||||
{
|
||||
return findCommonRootOutcome;
|
||||
}
|
||||
|
||||
InstanceOptionalReference instanceToCreate;
|
||||
{
|
||||
// Initialize Undo Batch object
|
||||
ScopedUndoBatch undoBatch("Create Prefab");
|
||||
|
||||
PrefabDom commonRootInstanceDomBeforeCreate;
|
||||
m_instanceToTemplateInterface->GenerateDomForInstance(
|
||||
commonRootInstanceDomBeforeCreate, commonRootEntityOwningInstance->get());
|
||||
|
||||
AZStd::vector<AZ::Entity*> entities;
|
||||
AZStd::vector<AZStd::unique_ptr<Instance>> instances;
|
||||
|
||||
// Retrieve all entities affected and identify Instances
|
||||
if (!RetrieveAndSortPrefabEntitiesAndInstances(inputEntityList, commonRootEntityOwningInstance->get(), entities, instances))
|
||||
{
|
||||
return AZ::Failure(
|
||||
AZStd::string("Could not create a new prefab out of the entities provided - entities do not share a common root."));
|
||||
}
|
||||
|
||||
// When we create a prefab with other prefab instances, we have to remove the existing links between the source and
|
||||
// target templates of the other instances.
|
||||
for (auto& nestedInstance : instances)
|
||||
{
|
||||
PrefabUndoHelpers::RemoveLink(
|
||||
nestedInstance->GetTemplateId(), commonRootEntityOwningInstance->get().GetTemplateId(),
|
||||
nestedInstance->GetInstanceAlias(), nestedInstance->GetLinkId(), undoBatch.GetUndoBatch());
|
||||
}
|
||||
|
||||
auto prefabEditorEntityOwnershipInterface = AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
if (!prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error "
|
||||
"(PrefabEditorEntityOwnershipInterface unavailable)."));
|
||||
}
|
||||
|
||||
// Create the Prefab
|
||||
instanceToCreate = prefabEditorEntityOwnershipInterface->CreatePrefab(
|
||||
entities, AZStd::move(instances), filePath, commonRootEntityOwningInstance);
|
||||
|
||||
if (!instanceToCreate)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error "
|
||||
"(A null instance is returned)."));
|
||||
}
|
||||
|
||||
PrefabUndoHelpers::UpdatePrefabInstance(
|
||||
commonRootEntityOwningInstance->get(), "Update prefab instance", commonRootInstanceDomBeforeCreate, undoBatch.GetUndoBatch());
|
||||
|
||||
CreateLink(
|
||||
topLevelEntities, instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch(),
|
||||
commonRootEntityId);
|
||||
AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId();
|
||||
|
||||
// Change top level entities to be parented to the container entity
|
||||
// Mark them as dirty so this change is correctly applied to the template
|
||||
for (AZ::Entity* topLevelEntity : topLevelEntities)
|
||||
{
|
||||
m_prefabUndoCache.UpdateCache(topLevelEntity->GetId());
|
||||
undoBatch.MarkEntityDirty(topLevelEntity->GetId());
|
||||
AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId);
|
||||
}
|
||||
|
||||
// Select Container Entity
|
||||
{
|
||||
auto selectionUndo = aznew SelectionCommand({containerEntityId}, "Select Prefab Container Entity");
|
||||
selectionUndo->SetParent(undoBatch.GetUndoBatch());
|
||||
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::RunRedoSeparately, selectionUndo);
|
||||
}
|
||||
}
|
||||
|
||||
// Save Template to file
|
||||
m_prefabLoaderInterface->SaveTemplate(instanceToCreate->get().GetTemplateId());
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::FindCommonRootOwningInstance(
|
||||
const AZStd::vector<AZ::EntityId>& entityIds, EntityList& inputEntityList, EntityList& topLevelEntities,
|
||||
AZ::EntityId& commonRootEntityId, InstanceOptionalReference& commonRootEntityOwningInstance)
|
||||
{
|
||||
// Retrieve entityList from entityIds
|
||||
EntityList inputEntityList = EntityIdListToEntityList(entityIds);
|
||||
inputEntityList = EntityIdListToEntityList(entityIds);
|
||||
|
||||
// Find common root and top level entities
|
||||
bool entitiesHaveCommonRoot = false;
|
||||
AZ::EntityId commonRootEntityId;
|
||||
EntityList topLevelEntities;
|
||||
|
||||
AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult(
|
||||
entitiesHaveCommonRoot,
|
||||
&AzToolsFramework::ToolsApplicationRequests::FindCommonRootInactive,
|
||||
inputEntityList,
|
||||
commonRootEntityId,
|
||||
&topLevelEntities
|
||||
);
|
||||
entitiesHaveCommonRoot, &AzToolsFramework::ToolsApplicationRequests::FindCommonRootInactive, inputEntityList,
|
||||
commonRootEntityId, &topLevelEntities);
|
||||
|
||||
// Bail if entities don't share a common root
|
||||
if (!entitiesHaveCommonRoot)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - entities do not share a common root."));
|
||||
}
|
||||
|
||||
AZ::Entity* commonRootEntity = nullptr;
|
||||
if (commonRootEntityId.IsValid())
|
||||
{
|
||||
commonRootEntity = GetEntityById(commonRootEntityId);
|
||||
return AZ::Failure(AZStd::string("Failed to create a prefab: Provided entities do not share a common root."));
|
||||
}
|
||||
|
||||
// Retrieve the owning instance of the common root entity, which will be our new instance's parent instance.
|
||||
InstanceOptionalReference commonRootEntityOwningInstance = GetOwnerInstanceByEntityId(commonRootEntityId);
|
||||
AZ_Assert(commonRootEntityOwningInstance.has_value(), "Failed to create prefab : "
|
||||
"Couldn't get a valid owning instance for the common root entity of the enities provided");
|
||||
|
||||
AZStd::vector<AZ::Entity*> entities;
|
||||
AZStd::vector<AZStd::unique_ptr<Instance>> instances;
|
||||
|
||||
// Retrieve all entities affected and identify Instances
|
||||
if (!RetrieveAndSortPrefabEntitiesAndInstances(inputEntityList, commonRootEntityOwningInstance->get(), entities, instances))
|
||||
commonRootEntityOwningInstance = GetOwnerInstanceByEntityId(commonRootEntityId);
|
||||
if (!commonRootEntityOwningInstance)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - entities do not share a common root."));
|
||||
AZ_Assert(
|
||||
false,
|
||||
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided");
|
||||
return AZ::Failure(AZStd::string(
|
||||
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided"));
|
||||
}
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
auto prefabEditorEntityOwnershipInterface = AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
|
||||
if (!prefabEditorEntityOwnershipInterface)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error "
|
||||
"(PrefabEditorEntityOwnershipInterface unavailable)."));
|
||||
}
|
||||
void PrefabPublicHandler::CreateLink(
|
||||
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId)
|
||||
{
|
||||
AZ::EntityId containerEntityId = sourceInstance.GetContainerEntityId();
|
||||
AZ::Entity* containerEntity = GetEntityById(containerEntityId);
|
||||
Prefab::PrefabDom containerEntityDomBefore;
|
||||
m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomBefore, *containerEntity);
|
||||
|
||||
InstanceOptionalReference instance = prefabEditorEntityOwnershipInterface->CreatePrefab(
|
||||
entities, AZStd::move(instances), filePath, commonRootEntityOwningInstance);
|
||||
|
||||
if (!instance)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not create a new prefab out of the entities provided - internal error "
|
||||
"(A null instance is returned)."));
|
||||
}
|
||||
|
||||
AZ::EntityId containerEntityId = instance->get().GetContainerEntityId();
|
||||
AZ::Vector3 containerEntityTranslation(AZ::Vector3::CreateZero());
|
||||
AZ::Quaternion containerEntityRotation(AZ::Quaternion::CreateZero());
|
||||
|
||||
// Set the transform (translation, rotation) of the container entity
|
||||
GenerateContainerEntityTransform(topLevelEntities, containerEntityTranslation, containerEntityRotation);
|
||||
|
||||
// Set container entity to be child of common root
|
||||
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetParent, commonRootEntityId);
|
||||
|
||||
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetLocalTranslation, containerEntityTranslation);
|
||||
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetLocalRotationQuaternion, containerEntityRotation);
|
||||
|
||||
// Set container entity to be child of common root
|
||||
AZ::TransformBus::Event(containerEntityId, &AZ::TransformBus::Events::SetParent, commonRootEntityId);
|
||||
|
||||
// Assign the EditorPrefabComponent to the instance container
|
||||
EntityCompositionRequests::AddComponentsOutcome outcome;
|
||||
EntityCompositionRequestBus::BroadcastResult(
|
||||
outcome, &EntityCompositionRequests::AddComponentsToEntities, EntityIdList{containerEntityId},
|
||||
AZ::ComponentTypeList{azrtti_typeid<AzToolsFramework::Prefab::EditorPrefabComponent>()});
|
||||
|
||||
// Change top level entities to be parented to the container entity
|
||||
for (AZ::Entity* topLevelEntity : topLevelEntities)
|
||||
{
|
||||
AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId);
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
PrefabDom containerEntityDomAfter;
|
||||
m_instanceToTemplateInterface->GenerateDomForEntity(containerEntityDomAfter, *containerEntity);
|
||||
|
||||
PrefabDom patch;
|
||||
m_instanceToTemplateInterface->GeneratePatch(patch, containerEntityDomBefore, containerEntityDomAfter);
|
||||
m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(patch, containerEntityId);
|
||||
|
||||
PrefabUndoHelpers::CreateLink(
|
||||
sourceInstance.GetTemplateId(), targetTemplateId, patch, sourceInstance.GetInstanceAlias(),
|
||||
undoBatch);
|
||||
|
||||
// Update the cache - this prevents these changes from being stored in the regular undo/redo nodes
|
||||
m_prefabUndoCache.Store(containerEntityId, AZStd::move(containerEntityDomAfter));
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::InstantiatePrefab(AZStd::string_view /*filePath*/, AZ::EntityId /*parent*/, AZ::Vector3 /*position*/)
|
||||
@@ -173,14 +245,7 @@ namespace AzToolsFramework
|
||||
AZStd::string("SavePrefab - Path error. Path could be invalid, or the prefab may not be loaded in this level."));
|
||||
}
|
||||
|
||||
auto prefabLoaderInterface = AZ::Interface<PrefabLoaderInterface>::Get();
|
||||
if (prefabLoaderInterface == nullptr)
|
||||
{
|
||||
return AZ::Failure(AZStd::string(
|
||||
"Could not save prefab - internal error (PrefabLoaderInterface unavailable)."));
|
||||
}
|
||||
|
||||
if (!prefabLoaderInterface->SaveTemplate(templateId))
|
||||
if (!m_prefabLoaderInterface->SaveTemplate(templateId))
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Could not save prefab - internal error (Json write operation failure)."));
|
||||
}
|
||||
@@ -261,13 +326,13 @@ namespace AzToolsFramework
|
||||
|
||||
if (instanceOptionalReference.has_value())
|
||||
{
|
||||
PrefabDom beforeState;
|
||||
m_prefabUndoCache.Retrieve(entityId, beforeState);
|
||||
|
||||
PrefabDom afterState;
|
||||
AZ::Entity* entity = GetEntityById(entityId);
|
||||
if (entity)
|
||||
{
|
||||
PrefabDom beforeState;
|
||||
m_prefabUndoCache.Retrieve(entityId, beforeState);
|
||||
|
||||
m_instanceToTemplateInterface->GenerateDomForEntity(afterState, *entity);
|
||||
|
||||
PrefabDom patch;
|
||||
@@ -286,7 +351,10 @@ namespace AzToolsFramework
|
||||
// Update the cache
|
||||
m_prefabUndoCache.Store(entityId, AZStd::move(afterState));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
m_prefabUndoCache.PurgeCache(entityId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -653,7 +721,7 @@ namespace AzToolsFramework
|
||||
InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entity->GetId());
|
||||
AZ_Assert(
|
||||
owningInstance.has_value(),
|
||||
"An error occored while retrieving entities and prefab instances : "
|
||||
"An error occurred while retrieving entities and prefab instances : "
|
||||
"Owning instance of entity with id '%llu' couldn't be found",
|
||||
entity->GetId());
|
||||
|
||||
@@ -737,7 +805,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
AZ_Assert(
|
||||
false,
|
||||
"An error occored in function EntitiesBelongToSameInstance: "
|
||||
"An error occurred in function EntitiesBelongToSameInstance: "
|
||||
"Owning instance of entity with id '%llu' couldn't be found",
|
||||
entityId);
|
||||
return false;
|
||||
|
||||
@@ -27,8 +27,10 @@ namespace AzToolsFramework
|
||||
namespace Prefab
|
||||
{
|
||||
class Instance;
|
||||
|
||||
class InstanceEntityMapperInterface;
|
||||
class InstanceToTemplateInterface;
|
||||
class PrefabLoaderInterface;
|
||||
class PrefabSystemComponentInterface;
|
||||
|
||||
class PrefabPublicHandler final
|
||||
@@ -67,12 +69,40 @@ namespace AzToolsFramework
|
||||
InstanceOptionalReference GetOwnerInstanceByEntityId(AZ::EntityId entityId) const;
|
||||
bool EntitiesBelongToSameInstance(const EntityIdList& entityIds) const;
|
||||
|
||||
/**
|
||||
* Creates a link between the templates of an instance and its parent.
|
||||
*
|
||||
* \param topLevelEntities The list of entities that are immediate children to the container entity of the instance.
|
||||
* \param sourceInstance The instance that corresponds to the source template of the link.
|
||||
* \param targetInstance The id of the target template.
|
||||
* \param undoBatch The undo batch to set as parent for this create link action.
|
||||
* \param commonRootEntityId The id of the entity that the source instance should be parented under.
|
||||
*/
|
||||
void CreateLink(
|
||||
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId);
|
||||
|
||||
/**
|
||||
* Given a list of entityIds, finds the prefab instance that owns the common root entity of the entityIds.
|
||||
*
|
||||
* \param entityIds The list of entity ids.
|
||||
* \param inputEntityList The list of entities corresponding to the entity ids.
|
||||
* \param topLevelEntities The list of entities that are immediate children of the common root entity.
|
||||
* \param commonRootEntityId The entity id of the common root entity of all the entityIds.
|
||||
* \param commonRootEntityOwningInstance The owning instance of the common root entity.
|
||||
* \return PrefabOperationResult indicating whether the action was successful or not.
|
||||
*/
|
||||
PrefabOperationResult FindCommonRootOwningInstance(
|
||||
const AZStd::vector<AZ::EntityId>& entityIds, EntityList& inputEntityList, EntityList& topLevelEntities,
|
||||
AZ::EntityId& commonRootEntityId, InstanceOptionalReference& commonRootEntityOwningInstance);
|
||||
|
||||
static Instance* GetParentInstance(Instance* instance);
|
||||
static Instance* GetAncestorOfInstanceThatIsChildOfRoot(const Instance* ancestor, Instance* descendant);
|
||||
static void GenerateContainerEntityTransform(const EntityList& topLevelEntities, AZ::Vector3& translation, AZ::Quaternion& rotation);
|
||||
|
||||
InstanceEntityMapperInterface* m_instanceEntityMapperInterface = nullptr;
|
||||
InstanceToTemplateInterface* m_instanceToTemplateInterface = nullptr;
|
||||
PrefabLoaderInterface* m_prefabLoaderInterface = nullptr;
|
||||
PrefabSystemComponentInterface* m_prefabSystemComponentInterface = nullptr;
|
||||
|
||||
// Caches entity states for undo/redo purposes
|
||||
|
||||
@@ -104,7 +104,6 @@ namespace AzToolsFramework
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
AZStd::unique_ptr<Instance> newInstance = AZStd::make_unique<Instance>(AZStd::move(containerEntity));
|
||||
|
||||
for (AZ::Entity* entity : entities)
|
||||
@@ -122,6 +121,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
newInstance->SetTemplateSourcePath(relativeFilePath);
|
||||
newInstance->SetContainerEntityName(relativeFilePath.Stem().Native());
|
||||
|
||||
TemplateId newTemplateId = CreateTemplateFromInstance(*newInstance);
|
||||
if (newTemplateId == InvalidTemplateId)
|
||||
@@ -142,7 +142,6 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabSystemComponent::PropagateTemplateChanges(TemplateId templateId)
|
||||
{
|
||||
UpdatePrefabInstances(templateId);
|
||||
auto templateIdToLinkIdsIterator = m_templateToLinkIdsMap.find(templateId);
|
||||
if (templateIdToLinkIdsIterator != m_templateToLinkIdsMap.end())
|
||||
{
|
||||
@@ -153,15 +152,24 @@ namespace AzToolsFramework
|
||||
templateIdToLinkIdsIterator->second.end()));
|
||||
UpdateLinkedInstances(linkIdsToUpdateQueue);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdatePrefabInstances(templateId);
|
||||
}
|
||||
}
|
||||
|
||||
void PrefabSystemComponent::UpdatePrefabTemplate(TemplateId templateId, const PrefabDom& updatedDom)
|
||||
{
|
||||
PrefabDom& templateDomToUpdate = FindTemplateDom(templateId);
|
||||
if (AZ::JsonSerialization::Compare(templateDomToUpdate, updatedDom) != AZ::JsonSerializerCompareResult::Equal)
|
||||
auto templateToUpdate = FindTemplate(templateId);
|
||||
if (templateToUpdate)
|
||||
{
|
||||
templateDomToUpdate.CopyFrom(updatedDom, templateDomToUpdate.GetAllocator());
|
||||
PropagateTemplateChanges(templateId);
|
||||
PrefabDom& templateDomToUpdate = templateToUpdate->get().GetPrefabDom();
|
||||
if (AZ::JsonSerialization::Compare(templateDomToUpdate, updatedDom) != AZ::JsonSerializerCompareResult::Equal)
|
||||
{
|
||||
templateDomToUpdate.CopyFrom(updatedDom, templateDomToUpdate.GetAllocator());
|
||||
templateToUpdate->get().MarkAsDirty(true);
|
||||
PropagateTemplateChanges(templateId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -615,7 +623,12 @@ namespace AzToolsFramework
|
||||
instancesValue = memberFound->value;
|
||||
}
|
||||
|
||||
instancesValue->get().AddMember(rapidjson::StringRef(instanceAlias.c_str()), PrefabDomValue(), targetTemplateDom.GetAllocator());
|
||||
// Only add the instance if it's not there already
|
||||
if (instancesValue->get().FindMember(rapidjson::StringRef(instanceAlias.c_str())) == instancesValue->get().MemberEnd())
|
||||
{
|
||||
instancesValue->get().AddMember(
|
||||
rapidjson::StringRef(instanceAlias.c_str()), PrefabDomValue(), targetTemplateDom.GetAllocator());
|
||||
}
|
||||
|
||||
Template& sourceTemplate = sourceTemplateRef->get();
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& targetId,
|
||||
const TemplateId& sourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
const PrefabDomReference linkDom,
|
||||
PrefabDomReference linkDom,
|
||||
const LinkId linkId)
|
||||
{
|
||||
m_targetId = targetId;
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& targetId,
|
||||
const TemplateId& sourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
const PrefabDomReference linkDom = PrefabDomReference(),
|
||||
PrefabDomReference linkDom = PrefabDomReference(),
|
||||
const LinkId linkId = InvalidLinkId);
|
||||
|
||||
void Undo() override;
|
||||
|
||||
@@ -32,6 +32,28 @@ namespace AzToolsFramework
|
||||
state->SetParent(undoBatch);
|
||||
state->Redo();
|
||||
}
|
||||
|
||||
void CreateLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch,
|
||||
const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
auto linkAddUndo = aznew PrefabUndoInstanceLink("Create Link");
|
||||
linkAddUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, patch, InvalidLinkId);
|
||||
linkAddUndo->SetParent(undoBatch);
|
||||
linkAddUndo->Redo();
|
||||
}
|
||||
|
||||
void RemoveLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias,
|
||||
LinkId linkId, UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
auto linkRemoveUndo = aznew PrefabUndoInstanceLink("Remove Link");
|
||||
PrefabDom emptyLinkDom;
|
||||
linkRemoveUndo->Capture(
|
||||
targetTemplateId, sourceTemplateId, instanceAlias, emptyLinkDom, linkId);
|
||||
linkRemoveUndo->SetParent(undoBatch);
|
||||
linkRemoveUndo->Redo();
|
||||
}
|
||||
}
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -21,6 +21,12 @@ namespace AzToolsFramework
|
||||
void UpdatePrefabInstance(
|
||||
const Instance& instance, AZStd::string_view undoMessage, const PrefabDom& instanceDomBeforeUpdate,
|
||||
UndoSystem::URSequencePoint* undoBatch);
|
||||
void CreateLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch,
|
||||
const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch);
|
||||
void RemoveLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias,
|
||||
LinkId linkId, UndoSystem::URSequencePoint* undoBatch);
|
||||
}
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+5
@@ -61,6 +61,11 @@ namespace AzToolsFramework
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorEntityUiHandlerBase::CanRename(AZ::EntityId /*entityId*/) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditorEntityUiHandlerBase::PaintItemBackground(QPainter* /*painter*/, const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/) const
|
||||
{
|
||||
}
|
||||
|
||||
+2
@@ -47,6 +47,8 @@ namespace AzToolsFramework
|
||||
virtual QPixmap GenerateItemIcon(AZ::EntityId entityId) const;
|
||||
//! Returns whether the element's lock and visibility state should be accessible in the Outliner
|
||||
virtual bool CanToggleLockVisibility(AZ::EntityId entityId) const;
|
||||
//! Returns whether the element's name should be editable
|
||||
virtual bool CanRename(AZ::EntityId entityId) const;
|
||||
|
||||
//! Paints the background of the item in the Outliner.
|
||||
virtual void PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
|
||||
+4
@@ -192,6 +192,10 @@ namespace LegacyFramework
|
||||
// if we're in console mode, listen for CTRL+C
|
||||
::SetConsoleCtrlHandler(CTRL_BREAK_HandlerRoutine, true);
|
||||
#endif
|
||||
|
||||
m_ptrCommandLineParser = aznew AzFramework::CommandLine();
|
||||
m_ptrCommandLineParser->Parse(m_desc.m_argc, m_desc.m_argv);
|
||||
|
||||
// If we don't have one create a serialize context
|
||||
if (GetSerializeContext() == nullptr)
|
||||
{
|
||||
|
||||
+22
-22
@@ -945,6 +945,12 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
// Disable reparenting to the root level
|
||||
if (!newParentId.IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ignore entities not owned by the editor context. It is assumed that all entities belong
|
||||
// to the same context since multiple selection doesn't span across views.
|
||||
for (const AZ::EntityId& entityId : selectedEntityIds)
|
||||
@@ -974,39 +980,33 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
if (newParentId.IsValid())
|
||||
bool isLayerEntity = false;
|
||||
Layers::EditorLayerComponentRequestBus::EventResult(
|
||||
isLayerEntity,
|
||||
entityId,
|
||||
&Layers::EditorLayerComponentRequestBus::Events::HasLayer);
|
||||
// Layers can only have other layers as parents, or have no parent.
|
||||
if (isLayerEntity)
|
||||
{
|
||||
bool isLayerEntity = false;
|
||||
bool newParentIsLayer = false;
|
||||
Layers::EditorLayerComponentRequestBus::EventResult(
|
||||
isLayerEntity,
|
||||
entityId,
|
||||
newParentIsLayer,
|
||||
newParentId,
|
||||
&Layers::EditorLayerComponentRequestBus::Events::HasLayer);
|
||||
// Layers can only have other layers as parents, or have no parent.
|
||||
if (isLayerEntity)
|
||||
if (!newParentIsLayer)
|
||||
{
|
||||
bool newParentIsLayer = false;
|
||||
Layers::EditorLayerComponentRequestBus::EventResult(
|
||||
newParentIsLayer,
|
||||
newParentId,
|
||||
&Layers::EditorLayerComponentRequestBus::Events::HasLayer);
|
||||
if (!newParentIsLayer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Only check the entity pointer if the entity id is valid because
|
||||
//we want to allow dragging items to unoccupied parts of the tree to un-parent them
|
||||
if (newParentId.IsValid())
|
||||
AZ::Entity* newParentEntity = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(newParentEntity, &AZ::ComponentApplicationRequests::FindEntity, newParentId);
|
||||
if (!newParentEntity)
|
||||
{
|
||||
AZ::Entity* newParentEntity = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(newParentEntity, &AZ::ComponentApplicationRequests::FindEntity, newParentId);
|
||||
if (!newParentEntity)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//reject dragging on to yourself or your children
|
||||
|
||||
+24
-5
@@ -30,6 +30,7 @@
|
||||
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
#include <AzToolsFramework/UI/ComponentPalette/ComponentPaletteUtil.hxx>
|
||||
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiHandlerBase.h>
|
||||
#include <AzToolsFramework/UI/Outliner/EntityOutlinerDisplayOptionsMenu.h>
|
||||
#include <AzToolsFramework/UI/Outliner/EntityOutlinerListModel.hxx>
|
||||
#include <AzToolsFramework/UI/Outliner/EntityOutlinerSortFilterProxyModel.hxx>
|
||||
@@ -271,6 +272,12 @@ namespace AzToolsFramework
|
||||
|
||||
m_listModel->Initialize();
|
||||
|
||||
m_editorEntityUiInterface = AZ::Interface<AzToolsFramework::EditorEntityUiInterface>::Get();
|
||||
|
||||
AZ_Assert(
|
||||
m_editorEntityUiInterface != nullptr,
|
||||
"EntityOutlinerWidget requires a EditorEntityUiInterface instance on Initialize.");
|
||||
|
||||
EditorPickModeNotificationBus::Handler::BusConnect(GetEntityContextId());
|
||||
EntityHighlightMessages::Bus::Handler::BusConnect();
|
||||
EntityOutlinerModelNotificationBus::Handler::BusConnect();
|
||||
@@ -562,7 +569,13 @@ namespace AzToolsFramework
|
||||
|
||||
if (m_selectedEntityIds.size() == 1)
|
||||
{
|
||||
contextMenu->addAction(m_actionToRenameSelection);
|
||||
auto entityId = m_selectedEntityIds.front();
|
||||
auto entityUiHandler = m_editorEntityUiInterface->GetHandler(entityId);
|
||||
|
||||
if (!entityUiHandler || entityUiHandler->CanRename(entityId))
|
||||
{
|
||||
contextMenu->addAction(m_actionToRenameSelection);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_selectedEntityIds.size() == 1)
|
||||
@@ -688,11 +701,17 @@ namespace AzToolsFramework
|
||||
|
||||
if (m_selectedEntityIds.size() == 1)
|
||||
{
|
||||
const QModelIndex proxyIndex = GetIndexFromEntityId(m_selectedEntityIds.front());
|
||||
if (proxyIndex.isValid())
|
||||
auto entityId = m_selectedEntityIds.front();
|
||||
auto entityUiHandler = m_editorEntityUiInterface->GetHandler(entityId);
|
||||
|
||||
if (!entityUiHandler || entityUiHandler->CanRename(entityId))
|
||||
{
|
||||
m_gui->m_objectTree->setCurrentIndex(proxyIndex);
|
||||
m_gui->m_objectTree->QTreeView::edit(proxyIndex);
|
||||
const QModelIndex proxyIndex = GetIndexFromEntityId(entityId);
|
||||
if (proxyIndex.isValid())
|
||||
{
|
||||
m_gui->m_objectTree->setCurrentIndex(proxyIndex);
|
||||
m_gui->m_objectTree->QTreeView::edit(proxyIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace Ui
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
class EditorEntityUiInterface;
|
||||
class EntityOutlinerListModel;
|
||||
class EntityOutlinerSortFilterProxyModel;
|
||||
|
||||
@@ -193,6 +194,8 @@ namespace AzToolsFramework
|
||||
EntityIdSet m_entitiesToSort;
|
||||
EntityOutliner::DisplaySortMode m_sortMode;
|
||||
bool m_sortContentQueued;
|
||||
|
||||
EditorEntityUiInterface* m_editorEntityUiInterface = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -50,11 +50,31 @@ namespace AzToolsFramework
|
||||
return QPixmap(m_levelRootIconPath);
|
||||
}
|
||||
|
||||
QString LevelRootUiHandler::GenerateItemInfoString(AZ::EntityId entityId) const
|
||||
{
|
||||
QString infoString;
|
||||
|
||||
AZ::IO::Path path = m_prefabPublicInterface->GetOwningInstancePrefabPath(entityId);
|
||||
|
||||
if (!path.empty())
|
||||
{
|
||||
infoString =
|
||||
QObject::tr("<span style=\"font-style: italic; font-weight: 400;\">(%1)</span>").arg(path.Filename().Native().data());
|
||||
}
|
||||
|
||||
return infoString;
|
||||
}
|
||||
|
||||
bool LevelRootUiHandler::CanToggleLockVisibility(AZ::EntityId /*entityId*/) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LevelRootUiHandler::CanRename(AZ::EntityId /*entityId*/) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void LevelRootUiHandler::PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& /*index*/) const
|
||||
{
|
||||
if (!painter)
|
||||
|
||||
@@ -34,7 +34,9 @@ namespace AzToolsFramework
|
||||
|
||||
// EditorEntityUiHandler...
|
||||
QPixmap GenerateItemIcon(AZ::EntityId entityId) const override;
|
||||
QString GenerateItemInfoString(AZ::EntityId entityId) const override;
|
||||
bool CanToggleLockVisibility(AZ::EntityId entityId) const override;
|
||||
bool CanRename(AZ::EntityId entityId) const override;
|
||||
void PaintItemBackground(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||
|
||||
private:
|
||||
|
||||
+47
-10
@@ -310,6 +310,9 @@ namespace AzToolsFramework
|
||||
{
|
||||
initEntityPropertyEditorResources();
|
||||
|
||||
m_prefabPublicInterface = AZ::Interface<Prefab::PrefabPublicInterface>::Get();
|
||||
AZ_Assert(m_prefabPublicInterface != nullptr, "EntityPropertyEditor requires a PrefabPublicInterface instance on Initialize.");
|
||||
|
||||
setObjectName("EntityPropertyEditor");
|
||||
setAcceptDrops(true);
|
||||
|
||||
@@ -405,8 +408,6 @@ namespace AzToolsFramework
|
||||
CreateActions();
|
||||
UpdateContents();
|
||||
|
||||
m_prefabPublicInterface = AZ::Interface<Prefab::PrefabPublicInterface>::Get();
|
||||
|
||||
EditorEntityContextNotificationBus::Handler::BusConnect();
|
||||
|
||||
//forced to register global event filter with application for selection
|
||||
@@ -693,11 +694,38 @@ namespace AzToolsFramework
|
||||
m_gui->m_entityIcon->repaint();
|
||||
}
|
||||
|
||||
EntityPropertyEditor::InspectorLayout EntityPropertyEditor::GetCurrentInspectorLayout() const
|
||||
{
|
||||
if (!m_prefabsAreEnabled)
|
||||
{
|
||||
return m_isLevelEntityEditor ? InspectorLayout::LEVEL : InspectorLayout::ENTITY;
|
||||
}
|
||||
|
||||
AZ::EntityId levelContainerEntityId = m_prefabPublicInterface->GetLevelInstanceContainerEntityId();
|
||||
if (AZStd::find(m_selectedEntityIds.begin(), m_selectedEntityIds.end(), levelContainerEntityId) != m_selectedEntityIds.end())
|
||||
{
|
||||
if (m_selectedEntityIds.size() > 1)
|
||||
{
|
||||
return InspectorLayout::INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
return InspectorLayout::LEVEL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return InspectorLayout::ENTITY;
|
||||
}
|
||||
}
|
||||
|
||||
void EntityPropertyEditor::UpdateEntityDisplay()
|
||||
{
|
||||
UpdateStatusComboBox();
|
||||
|
||||
if (m_isLevelEntityEditor)
|
||||
InspectorLayout layout = GetCurrentInspectorLayout();
|
||||
|
||||
if (layout == InspectorLayout::LEVEL)
|
||||
{
|
||||
AZStd::string levelName;
|
||||
AzToolsFramework::EditorRequestBus::BroadcastResult(levelName, &AzToolsFramework::EditorRequests::GetLevelName);
|
||||
@@ -737,13 +765,20 @@ namespace AzToolsFramework
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
SelectionEntityTypeInfo result = SelectionEntityTypeInfo::None;
|
||||
|
||||
if (m_isLevelEntityEditor)
|
||||
InspectorLayout layout = GetCurrentInspectorLayout();
|
||||
|
||||
if (layout == InspectorLayout::LEVEL)
|
||||
{
|
||||
// The Level Inspector should only have a list of selectable components after the
|
||||
// level entity itself is valid (i.e. "selected").
|
||||
return selection.empty() ? SelectionEntityTypeInfo::None : SelectionEntityTypeInfo::LevelEntity;
|
||||
}
|
||||
|
||||
if (layout == InspectorLayout::INVALID)
|
||||
{
|
||||
return SelectionEntityTypeInfo::Mixed;
|
||||
}
|
||||
|
||||
for (AZ::EntityId selectedEntityId : selection)
|
||||
{
|
||||
bool isLayerEntity = false;
|
||||
@@ -909,16 +944,18 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
bool isLevelLayout = GetCurrentInspectorLayout() == InspectorLayout::LEVEL;
|
||||
|
||||
m_gui->m_entityDetailsLabel->setText(entityDetailsLabelText);
|
||||
m_gui->m_entityDetailsLabel->setVisible(entityDetailsVisible);
|
||||
m_gui->m_entityNameEditor->setVisible(hasEntitiesDisplayed);
|
||||
m_gui->m_entityNameLabel->setVisible(hasEntitiesDisplayed);
|
||||
m_gui->m_entityIcon->setVisible(hasEntitiesDisplayed);
|
||||
m_gui->m_pinButton->setVisible(m_overrideSelectedEntityIds.empty() && hasEntitiesDisplayed && !m_isSystemEntityEditor && !m_isLevelEntityEditor);
|
||||
m_gui->m_statusLabel->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !m_isLevelEntityEditor);
|
||||
m_gui->m_statusComboBox->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !m_isLevelEntityEditor);
|
||||
m_gui->m_entityIdLabel->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !m_isLevelEntityEditor);
|
||||
m_gui->m_entityIdText->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !m_isLevelEntityEditor);
|
||||
m_gui->m_pinButton->setVisible(m_overrideSelectedEntityIds.empty() && hasEntitiesDisplayed && !m_isSystemEntityEditor);
|
||||
m_gui->m_statusLabel->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
|
||||
m_gui->m_statusComboBox->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
|
||||
m_gui->m_entityIdLabel->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
|
||||
m_gui->m_entityIdText->setVisible(hasEntitiesDisplayed && !m_isSystemEntityEditor && !isLevelLayout);
|
||||
|
||||
bool displayComponentSearchBox = hasEntitiesDisplayed;
|
||||
if (hasEntitiesDisplayed)
|
||||
@@ -941,7 +978,7 @@ namespace AzToolsFramework
|
||||
UpdateEntityDisplay();
|
||||
}
|
||||
|
||||
m_gui->m_darkBox->setVisible(displayComponentSearchBox && !m_isSystemEntityEditor && !m_isLevelEntityEditor);
|
||||
m_gui->m_darkBox->setVisible(displayComponentSearchBox && !m_isSystemEntityEditor && !isLevelLayout);
|
||||
m_gui->m_entitySearchBox->setVisible(displayComponentSearchBox);
|
||||
|
||||
bool displayAddComponentMenu = CanAddComponentsToSelection(selectionEntityTypeInfo);
|
||||
|
||||
+9
@@ -521,6 +521,15 @@ namespace AzToolsFramework
|
||||
bool m_isSystemEntityEditor;
|
||||
bool m_isLevelEntityEditor = false;
|
||||
|
||||
enum class InspectorLayout
|
||||
{
|
||||
ENTITY = 0, // All selected entities are regular entities
|
||||
LEVEL, // The selected entity is the level prefab container entity
|
||||
INVALID // Other entities are selected alongside the level prefab container entity
|
||||
};
|
||||
|
||||
InspectorLayout GetCurrentInspectorLayout() const;
|
||||
|
||||
// the spacer's job is to make sure that its always at the end of the list of components.
|
||||
QSpacerItem* m_spacer;
|
||||
bool m_isAlreadyQueuedRefresh;
|
||||
|
||||
@@ -28,8 +28,9 @@ ly_add_target(
|
||||
${pal_dir}
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
3rdParty::OpenSSL
|
||||
AZ::AzCore
|
||||
PUBLIC
|
||||
3rdParty::OpenSSL
|
||||
)
|
||||
|
||||
ly_add_source_properties(
|
||||
|
||||
Reference in New Issue
Block a user