diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp index 63a0554e37..ee9ab21ba2 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.cpp @@ -224,6 +224,22 @@ namespace EMStudio return m_entityContext->GetContextId(); } + void AnimViewportRenderer::CheckBounds() + { + AZ::Vector3 groundPos; + AZ::TransformBus::EventResult(groundPos, m_groundEntity->GetId(), &AZ::TransformBus::Events::GetWorldTranslation); + + const AZ::Vector3 characterPos = GetCharacterCenter(); + if (AZStd::abs(characterPos.GetX() - groundPos.GetX()) > BoundMaxDistance || + AZStd::abs(characterPos.GetY() - groundPos.GetY()) > BoundMaxDistance) + { + const float tileOffsetX = AZStd::fmod(characterPos.GetX(), TileSize); + const float tileOffsetY = AZStd::fmod(characterPos.GetX(), TileSize); + const AZ::Vector3 newGroundPos(characterPos.GetX() - tileOffsetX, characterPos.GetY() - tileOffsetY, groundPos.GetZ()); + AZ::TransformBus::Event(m_groundEntity->GetId(), &AZ::TransformBus::Events::SetWorldTranslation, newGroundPos); + } + } + void AnimViewportRenderer::ResetEnvironment() { // Reset environment diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h index 3f34d2f26e..7331052380 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportRenderer.h @@ -59,6 +59,9 @@ namespace EMStudio AZ::EntityId GetEntityId() const; AzFramework::EntityContextId GetEntityContextId() const; + // Call this function on update to prevent the character going out of bounds of the ground. + void CheckBounds(); + private: // This function resets the light, camera and other environment settings. @@ -91,6 +94,8 @@ namespace EMStudio const RenderOptions* m_renderOptions; const float DefaultFrustumDimension = 128.0f; + const float BoundMaxDistance = 150.0f; + const float TileSize = 1.0f; AZStd::vector m_lightHandles; }; } diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp index 45c0061771..c240ba09d8 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Tools/EMStudio/AnimViewportWidget.cpp @@ -206,6 +206,7 @@ namespace EMStudio CalculateCameraProjection(); RenderCustomPluginData(); FollowCharacter(); + m_renderer->CheckBounds(); } void AnimViewportWidget::CalculateCameraProjection()