From f8dc8ab903a9f246240a08d79b8683bfd05ae153 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sun, 23 Nov 2025 14:19:11 -0600 Subject: [PATCH 1/4] Fix not being able to replay same animation in animation slot. --- Source/Engine/Animations/Graph/AnimGroup.Animation.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp b/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp index fd62ec537..fe0ad52e1 100644 --- a/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp +++ b/Source/Engine/Animations/Graph/AnimGroup.Animation.cpp @@ -2441,10 +2441,14 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu { if (bucket.LoopsLeft == 0) { - // End playing animation + // End playing animation and reset bucket params value = tryGetValue(node->GetBox(1), Value::Null); bucket.Index = -1; slot.Animation = nullptr; + bucket.TimePosition = 0.0f; + bucket.BlendInPosition = 0.0f; + bucket.BlendOutPosition = 0.0f; + bucket.LoopsDone = 0; return; } From 2d56411e5f8f4a292b328eeac51b6c3d59fe04f5 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sun, 23 Nov 2025 14:19:37 -0600 Subject: [PATCH 2/4] Add slot stop methods without anim param. --- Source/Engine/Level/Actors/AnimatedModel.cpp | 24 ++++++++++++++++++++ Source/Engine/Level/Actors/AnimatedModel.h | 12 ++++++++++ 2 files changed, 36 insertions(+) diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp index ee66c6c77..a8c091eb9 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.cpp +++ b/Source/Engine/Level/Actors/AnimatedModel.cpp @@ -563,6 +563,20 @@ void AnimatedModel::StopSlotAnimation(const StringView& slotName, Animation* ani } } +void AnimatedModel::StopSlotAnimation(const StringView& slotName) +{ + for (auto& slot : GraphInstance.Slots) + { + if (slot.Name == slotName) + { + //slot.Animation = nullptr; // TODO: make an immediate version of this method and set the animation to nullptr. + if (slot.Animation != nullptr) + slot.Reset = true; + break; + } + } +} + void AnimatedModel::PauseSlotAnimation() { for (auto& slot : GraphInstance.Slots) @@ -601,6 +615,16 @@ bool AnimatedModel::IsPlayingSlotAnimation(const StringView& slotName, Animation return false; } +bool AnimatedModel::IsPlayingSlotAnimation(const StringView& slotName) +{ + for (auto& slot : GraphInstance.Slots) + { + if (slot.Name == slotName && !slot.Pause) + return true; + } + return false; +} + void AnimatedModel::ApplyRootMotion(const Transform& rootMotionDelta) { // Skip if no motion diff --git a/Source/Engine/Level/Actors/AnimatedModel.h b/Source/Engine/Level/Actors/AnimatedModel.h index a011be0d0..dc837c658 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.h +++ b/Source/Engine/Level/Actors/AnimatedModel.h @@ -414,6 +414,12 @@ public: /// The name of the slot. /// The animation to stop. API_FUNCTION() void StopSlotAnimation(const StringView& slotName, Animation* anim); + + /// + /// Stops the animation playback on the slot in Anim Graph. + /// + /// The name of the slot. + API_FUNCTION() void StopSlotAnimation(const StringView& slotName); /// /// Pauses all the animations playback on the all slots in Anim Graph. @@ -439,6 +445,12 @@ public: /// The animation to check. API_FUNCTION() bool IsPlayingSlotAnimation(const StringView& slotName, Animation* anim); + /// + /// Checks if the animation playback is active on the slot in Anim Graph (not paused). + /// + /// The name of the slot. + API_FUNCTION() bool IsPlayingSlotAnimation(const StringView& slotName); + private: void ApplyRootMotion(const Transform& rootMotionDelta); void SyncParameters(); From 0e627577fc1d039942b1fa10bd2bb4292c2ec377 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sun, 14 Dec 2025 15:00:44 -0600 Subject: [PATCH 3/4] Simplify code. --- Source/Engine/Level/Actors/AnimatedModel.cpp | 27 ++------------------ Source/Engine/Level/Actors/AnimatedModel.h | 16 ++---------- 2 files changed, 4 insertions(+), 39 deletions(-) diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp index a8c091eb9..991ac3e05 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.cpp +++ b/Source/Engine/Level/Actors/AnimatedModel.cpp @@ -554,20 +554,7 @@ void AnimatedModel::StopSlotAnimation(const StringView& slotName, Animation* ani { for (auto& slot : GraphInstance.Slots) { - if (slot.Animation == anim && slot.Name == slotName) - { - //slot.Animation = nullptr; // TODO: make an immediate version of this method and set the animation to nullptr. - slot.Reset = true; - break; - } - } -} - -void AnimatedModel::StopSlotAnimation(const StringView& slotName) -{ - for (auto& slot : GraphInstance.Slots) - { - if (slot.Name == slotName) + if ((slot.Animation == anim || anim == nullptr) && slot.Name == slotName) { //slot.Animation = nullptr; // TODO: make an immediate version of this method and set the animation to nullptr. if (slot.Animation != nullptr) @@ -609,17 +596,7 @@ bool AnimatedModel::IsPlayingSlotAnimation(const StringView& slotName, Animation { for (auto& slot : GraphInstance.Slots) { - if (slot.Animation == anim && slot.Name == slotName && !slot.Pause) - return true; - } - return false; -} - -bool AnimatedModel::IsPlayingSlotAnimation(const StringView& slotName) -{ - for (auto& slot : GraphInstance.Slots) - { - if (slot.Name == slotName && !slot.Pause) + if ((slot.Animation == anim || anim == nullptr) && slot.Name == slotName && !slot.Pause) return true; } return false; diff --git a/Source/Engine/Level/Actors/AnimatedModel.h b/Source/Engine/Level/Actors/AnimatedModel.h index dc837c658..344f633cc 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.h +++ b/Source/Engine/Level/Actors/AnimatedModel.h @@ -413,13 +413,7 @@ public: /// /// The name of the slot. /// The animation to stop. - API_FUNCTION() void StopSlotAnimation(const StringView& slotName, Animation* anim); - - /// - /// Stops the animation playback on the slot in Anim Graph. - /// - /// The name of the slot. - API_FUNCTION() void StopSlotAnimation(const StringView& slotName); + API_FUNCTION() void StopSlotAnimation(const StringView& slotName, Animation* anim = nullptr); /// /// Pauses all the animations playback on the all slots in Anim Graph. @@ -443,13 +437,7 @@ public: /// /// The name of the slot. /// The animation to check. - API_FUNCTION() bool IsPlayingSlotAnimation(const StringView& slotName, Animation* anim); - - /// - /// Checks if the animation playback is active on the slot in Anim Graph (not paused). - /// - /// The name of the slot. - API_FUNCTION() bool IsPlayingSlotAnimation(const StringView& slotName); + API_FUNCTION() bool IsPlayingSlotAnimation(const StringView& slotName, Animation* anim = nullptr); private: void ApplyRootMotion(const Transform& rootMotionDelta); From 056de752ed02d9d145ef7eee61e08267f589d63f Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 14 Dec 2025 23:03:34 +0100 Subject: [PATCH 4/4] Add docs --- Source/Engine/Level/Actors/AnimatedModel.cpp | 2 +- Source/Engine/Level/Actors/AnimatedModel.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp index 991ac3e05..343710183 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.cpp +++ b/Source/Engine/Level/Actors/AnimatedModel.cpp @@ -574,7 +574,7 @@ void AnimatedModel::PauseSlotAnimation(const StringView& slotName, Animation* an { for (auto& slot : GraphInstance.Slots) { - if (slot.Animation == anim && slot.Name == slotName) + if ((slot.Animation == anim || anim == nullptr) && slot.Name == slotName) { slot.Pause = true; break; diff --git a/Source/Engine/Level/Actors/AnimatedModel.h b/Source/Engine/Level/Actors/AnimatedModel.h index 344f633cc..a520d6723 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.h +++ b/Source/Engine/Level/Actors/AnimatedModel.h @@ -412,7 +412,7 @@ public: /// Stops the animation playback on the slot in Anim Graph. /// /// The name of the slot. - /// The animation to stop. + /// The animation to check. Null to use slot name only. API_FUNCTION() void StopSlotAnimation(const StringView& slotName, Animation* anim = nullptr); /// @@ -424,8 +424,8 @@ public: /// Pauses the animation playback on the slot in Anim Graph. /// /// The name of the slot. - /// The animation to pause. - API_FUNCTION() void PauseSlotAnimation(const StringView& slotName, Animation* anim); + /// The animation to check. Null to use slot name only. + API_FUNCTION() void PauseSlotAnimation(const StringView& slotName, Animation* anim = nullptr); /// /// Checks if any animation playback is active on any slot in Anim Graph (not paused). @@ -436,7 +436,7 @@ public: /// Checks if the animation playback is active on the slot in Anim Graph (not paused). /// /// The name of the slot. - /// The animation to check. + /// The animation to check. Null to use slot name only. API_FUNCTION() bool IsPlayingSlotAnimation(const StringView& slotName, Animation* anim = nullptr); private: