Skip to content

Commit 92c08b8

Browse files
authored
Merge pull request o3de#17469 from aws-lumberyard-dev/LYN-19166_RemoveMeshAndMaterialFromServerSpawnable
Remove Visual Components from Headless Spawnable Assets
2 parents e6fe438 + 51f2b15 commit 92c08b8

File tree

7 files changed

+391
-0
lines changed

7 files changed

+391
-0
lines changed

Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <AzToolsFramework/Prefab/Instance/InstanceEntityIdMapper.h>
1919
#include <AzToolsFramework/Prefab/Instance/InstanceSerializer.h>
2020
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
21+
#include <AzToolsFramework/Prefab/Spawnable/AssetPlatformComponentRemover.h>
2122
#include <AzToolsFramework/Prefab/Spawnable/EditorInfoRemover.h>
2223
#include <AzToolsFramework/Prefab/Spawnable/PrefabCatchmentProcessor.h>
2324
#include <AzToolsFramework/Prefab/Spawnable/PrefabConversionPipeline.h>
@@ -68,6 +69,7 @@ namespace AzToolsFramework
6869
Instance::Reflect(context);
6970
AzToolsFramework::Prefab::PrefabConversionUtils::PrefabConversionPipeline::Reflect(context);
7071
AzToolsFramework::Prefab::PrefabConversionUtils::PrefabCatchmentProcessor::Reflect(context);
72+
AzToolsFramework::Prefab::PrefabConversionUtils::AssetPlatformComponentRemover::Reflect(context);
7173
AzToolsFramework::Prefab::PrefabConversionUtils::EditorInfoRemover::Reflect(context);
7274
PrefabPublicRequestHandler::Reflect(context);
7375
PrefabPublicNotificationHandler::Reflect(context);
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright (c) Contributors to the Open 3D Engine Project.
3+
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
4+
*
5+
* SPDX-License-Identifier: Apache-2.0 OR MIT
6+
*
7+
*/
8+
9+
#include "AssetPlatformComponentRemover.h"
10+
11+
#include <AzCore/Component/ComponentApplicationBus.h>
12+
#include <AzCore/RTTI/ReflectContext.h>
13+
#include <AzCore/Serialization/SerializeContext.h>
14+
#include <AzToolsFramework/Prefab/Spawnable/PrefabDocument.h>
15+
16+
17+
namespace AzToolsFramework::Prefab::PrefabConversionUtils
18+
{
19+
void AssetPlatformComponentRemover::Reflect(AZ::ReflectContext* context)
20+
{
21+
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
22+
{
23+
serializeContext->Class<AssetPlatformComponentRemover, PrefabProcessor>()
24+
->Version(1)
25+
->Field("PlatformExcludedComponents", &AssetPlatformComponentRemover::m_platformExcludedComponents)
26+
;
27+
}
28+
}
29+
30+
void AssetPlatformComponentRemover::Process(PrefabProcessorContext& prefabProcessorContext)
31+
{
32+
AZ::PlatformTagSet platformTags = prefabProcessorContext.GetPlatformTags();
33+
AZStd::set<AZ::Uuid> excludedComponents;
34+
for (const auto& platforms : m_platformExcludedComponents)
35+
{
36+
if (platformTags.contains(AZ::Crc32(platforms.first)))
37+
{
38+
excludedComponents.insert_range(platforms.second);
39+
}
40+
}
41+
42+
if (excludedComponents.empty())
43+
{
44+
// No need to remove any components.
45+
return;
46+
}
47+
48+
// Iterate over every entity, in every prefab
49+
prefabProcessorContext.ListPrefabs(
50+
[&prefabProcessorContext, &excludedComponents](PrefabDocument& prefab) -> void
51+
{
52+
prefab.GetInstance().GetAllEntitiesInHierarchy(
53+
[&prefab, &prefabProcessorContext, &excludedComponents](AZStd::unique_ptr<AZ::Entity>& entity) -> bool
54+
{
55+
// Loop over an entity's components backwards and pop-off components that shouldn't exist.
56+
AZStd::vector<AZ::Component*> components = entity->GetComponents();
57+
const int oldComponentCount = components.size();
58+
for (int i = oldComponentCount - 1; i >= 0; --i)
59+
{
60+
AZ::Component* component = components[i];
61+
if (excludedComponents.contains(component->GetUnderlyingComponentType()))
62+
{
63+
entity->RemoveComponent(component);
64+
delete component;
65+
}
66+
}
67+
68+
// Make sure we didn't remove any components that another component dependends on
69+
if (oldComponentCount != entity->GetComponents().size())
70+
{
71+
if (entity->EvaluateDependencies() == AZ::Entity::DependencySortResult::MissingRequiredService)
72+
{
73+
AZ_Error( "AssetPlatformComponentRemover", false,
74+
"Processing prefab '%s' failed! Removing components on entity '%s' has broken component "
75+
"dependency. Make sure you also remove any dependent components. If dependent component is actually required, "
76+
"then keep the provider. Please update Amazon/Tools/Prefab/Processing/PlatformExcludedComponents settings registry (.setreg).",
77+
prefab.GetName().c_str(),
78+
entity->GetName().c_str()
79+
);
80+
81+
prefabProcessorContext.ErrorEncountered();
82+
}
83+
}
84+
85+
// continue iterating over entities...
86+
return true;
87+
});
88+
});
89+
}
90+
} // namespace AzToolsFramework::Prefab::PrefabConversionUtils
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) Contributors to the Open 3D Engine Project.
3+
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
4+
*
5+
* SPDX-License-Identifier: Apache-2.0 OR MIT
6+
*
7+
*/
8+
9+
#pragma once
10+
11+
#include <AzCore/Memory/SystemAllocator.h>
12+
#include <AzCore/std/containers/map.h>
13+
#include <AzCore/std/containers/set.h>
14+
#include <AzToolsFramework/Prefab/Spawnable/PrefabProcessor.h>
15+
16+
namespace AZ
17+
{
18+
class ReflectContext;
19+
}
20+
21+
// Predefinition for unit test friend class
22+
namespace UnitTest
23+
{
24+
class PrefabProcessingTestFixture;
25+
}
26+
27+
namespace AzToolsFramework::Prefab::PrefabConversionUtils
28+
{
29+
//! A prefab processor for removing a spawnable's components based on asset tags.
30+
//! For example, a headless server shouldn't need to load a mesh or material asset,
31+
//! so remove any MeshComponents from the server asset spawnable.
32+
//! Excluded components are defined inside of Registry/prefab.tools.setreg
33+
class AssetPlatformComponentRemover
34+
: public PrefabProcessor
35+
{
36+
friend class UnitTest::PrefabProcessingTestFixture;
37+
38+
public:
39+
AZ_CLASS_ALLOCATOR(AssetPlatformComponentRemover, AZ::SystemAllocator);
40+
AZ_RTTI(AzToolsFramework::Prefab::PrefabConversionUtils::AssetPlatformComponentRemover,
41+
"{25D9A8A6-908F-4B26-A752-EBAF7DC074F8}", PrefabProcessor);
42+
43+
static void Reflect(AZ::ReflectContext* context);
44+
~AssetPlatformComponentRemover() override = default;
45+
46+
void Process(PrefabProcessorContext& prefabProcessorContext) override;
47+
48+
private:
49+
AZStd::map<AZStd::string, AZStd::set<AZ::Uuid>> m_platformExcludedComponents;
50+
};
51+
} // namespace AzToolsFramework::Prefab::PrefabConversionUtils

Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,8 @@ set(FILES
895895
Prefab/PrefabUndoHelpers.h
896896
Prefab/Spawnable/ComponentRequirementsValidator.h
897897
Prefab/Spawnable/ComponentRequirementsValidator.cpp
898+
Prefab/Spawnable/AssetPlatformComponentRemover.h
899+
Prefab/Spawnable/AssetPlatformComponentRemover.cpp
898900
Prefab/Spawnable/EditorInfoRemover.h
899901
Prefab/Spawnable/EditorInfoRemover.cpp
900902
Prefab/Spawnable/EditorOnlyEntityHandler/EditorOnlyEntityHandler.h

0 commit comments

Comments
 (0)