diff --git a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp index 27e59c0bf4..e9b7ace7c9 100644 --- a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp +++ b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp @@ -17,6 +17,8 @@ #include #include #include +#include +#include namespace Multiplayer { @@ -93,6 +95,41 @@ namespace Multiplayer }); } + static bool HasNetHierarchyComponents(const AZ::Entity* entity) + { + return (entity->FindComponent() != nullptr) + || (entity->FindComponent() != nullptr); + } + + static void ValidateNetHierarchies(const AZStd::vector& prefabNetEntities) + { + AZStd::unordered_map prefabEntitesMap; + + for (auto* entity : prefabNetEntities) + { + auto* entityTransform = entity->FindComponent(); + AZ_Assert(entityTransform, "Net entities have to have Transform Component"); + + AZ::EntityId parentId = entityTransform->GetParentId(); + + // The input entities array is sorted in the parent to children order, + // so we only need to check against already iterated entities + if (parentId.IsValid() && prefabEntitesMap.contains(parentId)) + { + AZ::Entity* parentEntity = prefabEntitesMap[parentId]; + bool parentValid = HasNetHierarchyComponents(parentEntity); + AZ_Error("NetworkPrefabProcessor", parentValid, "Parent Entity %s must have a Network Hierarchy component assigned", + parentEntity->GetName().c_str()); + + bool childValid = HasNetHierarchyComponents(entity); + AZ_Error("NetworkPrefabProcessor", childValid, "Child Entity %s must have a Network Hierarchy component assigned", + entity->GetName().c_str()); + } + + prefabEntitesMap[entity->GetId()] = entity; + } + } + void NetworkPrefabProcessor::ProcessPrefab(PrefabProcessorContext& context, AZStd::string_view prefabName, PrefabDom& prefab) { using namespace AzToolsFramework::Prefab; @@ -131,6 +168,9 @@ namespace Multiplayer // Sort the entities prior to processing. The entities will end up in the net spawnable in this order. SpawnableUtils::SortEntitiesByTransformHierarchy(prefabNetEntities); + // Here we validate the hierarchical net entities have one of Network Hierarchy components. + ValidateNetHierarchies(prefabNetEntities); + // Create an asset for our future network spawnable: this allows us to put references to the asset in the components AZ::Data::Asset networkSpawnableAsset; networkSpawnableAsset.Create(networkSpawnable->GetId());