CollidersPrefabConversion.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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. #include <AzCore/Asset/AssetManager.h>
  9. #include <AzCore/Console/IConsole.h>
  10. #include <AzFramework/API/ApplicationAPI.h>
  11. #include <EditorColliderComponent.h>
  12. #include <EditorShapeColliderComponent.h>
  13. #include <EditorRigidBodyComponent.h>
  14. #include <EditorStaticRigidBodyComponent.h>
  15. #include <Editor/Source/Components/Conversion/PrefabConversionUtils.h>
  16. namespace PhysX
  17. {
  18. void UpdatePrefabsWithColliderComponents(const AZ::ConsoleCommandContainer& commandArgs);
  19. AZ_CONSOLEFREEFUNC(
  20. "ed_physxUpdatePrefabsWithColliderComponents",
  21. UpdatePrefabsWithColliderComponents,
  22. AZ::ConsoleFunctorFlags::Null,
  23. "Finds entities with collider components and no rigid bodies and updates them to the new pattern which requires a static rigid body component.");
  24. bool AddStaticRigidBodyToPrefabEntity(
  25. Utils::PrefabInfo& prefabInfo,
  26. AzToolsFramework::Prefab::PrefabDomValue& entityPrefab)
  27. {
  28. AZ::Entity entity;
  29. Utils::PrefabEntityIdMapper prefabEntityIdMapper;
  30. if (!Utils::LoadPrefabEntity(prefabEntityIdMapper, entityPrefab, entity))
  31. {
  32. AZ_Warning(
  33. "PhysXColliderConversion",
  34. false,
  35. "Unable to load entity '%s' from prefab '%s'.",
  36. entity.GetName().c_str(),
  37. prefabInfo.m_prefabFullPath.c_str());
  38. return false;
  39. }
  40. if (!entity.CreateComponent<EditorStaticRigidBodyComponent>())
  41. {
  42. AZ_Warning(
  43. "PhysXColliderConversion",
  44. false,
  45. "Failed to create static rigid body component for entity '%s' in prefab '%s'.",
  46. entity.GetName().c_str(),
  47. prefabInfo.m_prefabFullPath.c_str());
  48. return false;
  49. }
  50. if (!Utils::StorePrefabEntity(prefabEntityIdMapper, prefabInfo.m_template->GetPrefabDom(), entityPrefab, entity))
  51. {
  52. AZ_Warning(
  53. "PhysXColliderConversion",
  54. false,
  55. "Unable to store entity '%s' into prefab '%s'.",
  56. entity.GetName().c_str(),
  57. prefabInfo.m_prefabFullPath.c_str());
  58. return false;
  59. }
  60. return true;
  61. }
  62. void UpdatePrefabPhysXColliders(Utils::PrefabInfo& prefabInfo)
  63. {
  64. bool prefabModified = false;
  65. for (auto* entity : Utils::GetPrefabEntities(prefabInfo.m_template->GetPrefabDom()))
  66. {
  67. const auto entityComponents = Utils::GetEntityComponents(*entity);
  68. const bool rigidBodyMissing = AZStd::none_of(
  69. entityComponents.begin(),
  70. entityComponents.end(),
  71. [](const auto* component)
  72. {
  73. const auto typeId = Utils::GetComponentTypeId(*component);
  74. return typeId == azrtti_typeid<EditorRigidBodyComponent>() || typeId == azrtti_typeid<EditorStaticRigidBodyComponent>();
  75. });
  76. const bool colliderPresent = AZStd::any_of(
  77. entityComponents.begin(),
  78. entityComponents.end(),
  79. [](const auto* component)
  80. {
  81. const auto typeId = Utils::GetComponentTypeId(*component);
  82. return typeId == azrtti_typeid<EditorColliderComponent>() || typeId == azrtti_typeid<EditorShapeColliderComponent>();
  83. });
  84. if (rigidBodyMissing && colliderPresent)
  85. {
  86. if (AddStaticRigidBodyToPrefabEntity(prefabInfo, *entity))
  87. {
  88. prefabModified = true;
  89. }
  90. }
  91. }
  92. if (prefabModified)
  93. {
  94. AZ_TracePrintf("PhysXColliderConversion", "Saving modified prefab '%s'.\n", prefabInfo.m_prefabFullPath.c_str());
  95. Utils::SavePrefab(prefabInfo);
  96. AZ_TracePrintf("PhysXColliderConversion", "\n");
  97. }
  98. }
  99. void UpdatePrefabsWithColliderComponents([[maybe_unused]] const AZ::ConsoleCommandContainer& commandArgs)
  100. {
  101. bool prefabSystemEnabled = false;
  102. AzFramework::ApplicationRequests::Bus::BroadcastResult(
  103. prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
  104. if (!prefabSystemEnabled)
  105. {
  106. AZ_TracePrintf("PhysXColliderConversion", "Prefabs system is not enabled. Prefabs won't be converted.\n");
  107. AZ_TracePrintf("PhysXColliderConversion", "\n");
  108. return;
  109. }
  110. AZ_TracePrintf("PhysXColliderConversion", "Searching for prefabs to convert...\n");
  111. AZ_TracePrintf("PhysXColliderConversion", "\n");
  112. AZStd::vector<Utils::PrefabInfo> prefabs = Utils::CollectPrefabs();
  113. if (prefabs.empty())
  114. {
  115. AZ_TracePrintf("PhysXColliderConversion", "No prefabs found.\n");
  116. AZ_TracePrintf("PhysXColliderConversion", "\n");
  117. return;
  118. }
  119. AZ_TracePrintf("PhysXColliderConversion", "Found %zu prefabs to check.\n", prefabs.size());
  120. AZ_TracePrintf("PhysXColliderConversion", "\n");
  121. for (auto& prefab : prefabs)
  122. {
  123. UpdatePrefabPhysXColliders(prefab);
  124. }
  125. AZ_TracePrintf("PhysXColliderConversion", "Prefab conversion finished.\n");
  126. AZ_TracePrintf("PhysXColliderConversion", "\n");
  127. }
  128. } // namespace PhysX