Description

If you use StartFrameOffset set to 1 or higher in conjunction with the Use Animation Blueprint, the character's animation will be rough towards the end of the section. Specifically, it seems that the animation specified in the section and its reference pose are switched every frame.

In UE5.1, the implementation of FMovieSceneSkeletalAnimationSectionTemplateParameters::MapTimeToAnimation was changed so that the calculation result including StartFrameOffset exceeds the animation playback range.

5.0

    AnimPosition += InFrameRate.AsSeconds(FirstLoopStartFrameOffset);
   if (SeqLength > 0.0 && (bLooping || !FMath::IsNearlyEqual(AnimPosition, SeqLength, 1e-4)))
   {
      AnimPosition = FMath::Fmod(AnimPosition, SeqLength);
   }
   AnimPosition += InFrameRate.AsSeconds(StartFrameOffset);
   if (bReverse)
   {
      AnimPosition = GetSequenceLength() - AnimPosition;
   }
 
   return AnimPosition;
} 

5.1

    // The Time from the beginning of SectionStartTime to InPosition in seconds
   double SecondsFromSectionStart = FFrameTime::FromDecimal((InPosition - SectionStartTime).AsDecimal() * AnimPlayRate) / InFrameRate;
 
   // Logic for reversed animation
   if (bReverse)
   {
      // Duration of this section 
      double SectionDuration = (((SectionEndTime - SectionStartTime) * AnimPlayRate) / InFrameRate);
      SecondsFromSectionStart = SectionDuration - SecondsFromSectionStart;
   }
 
   // Make sure Seconds is in range
   if (SeqLength > 0.0 && (bLooping || !FMath::IsNearlyEqual(SecondsFromSectionStart, SeqLength, 1e-4)))
   {
      SecondsFromSectionStart = FMath::Fmod(SecondsFromSectionStart, SeqLength);
   }
 
   // Add the StartFrameOffset and FirstLoopStartFrameOffset to the current seconds in the section to get the right animation frame
   SecondsFromSectionStart += InFrameRate.AsSeconds(StartFrameOffset) + InFrameRate.AsSeconds(FirstLoopStartFrameOffset);
   
   return SecondsFromSectionStart;
} 

So, FAnimMontageInstance::SetSequencerMontagePosition creates and destroys AnimMontage intermittently.

It is possible to fix the behavior by changing the timing of FMath::Fmod implementation in 5.1 as follows. But it will likely conflict with the changes made by other fix code.

double FMovieSceneSkeletalAnimationSectionTemplateParameters::MapTimeToAnimation(FFrameTime InPosition, FFrameRate InFrameRate) const
{
   ...
 
      //for fix
      SecondsFromSectionStart += InFrameRate.AsSeconds(FirstLoopStartFrameOffset);
   
   // Make sure Seconds is in range
   if (SeqLength > 0.0 && (bLooping || !FMath::IsNearlyEqual(SecondsFromSectionStart, SeqLength, 1e-4)))
   {
      SecondsFromSectionStart = FMath::Fmod(SecondsFromSectionStart, SeqLength);
   }
 
   // Add the StartFrameOffset and FirstLoopStartFrameOffset to the current seconds in the section to get the right animation frame
   // for fix
   //SecondsFromSectionStart += InFrameRate.AsSeconds(StartFrameOffset) + InFrameRate.AsSeconds(FirstLoopStartFrameOffset);
   SecondsFromSectionStart += InFrameRate.AsSeconds(StartFrameOffset);
   
   return SecondsFromSectionStart;
} 

 

Steps to Reproduce
  1. Open Repro proj
  2. Open LS_Repro
  3. Play

result : Character animation is erratic in the second half of the Animation track's section

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-175425 in the post.

0
Login to Vote

Fixed
ComponentUE - Anim - Sequencer - Anim in Engine
Affects Versions5.15.2
Target Fix5.2
Fix Commit23913557
Main Commit23923326
Release Commit23913557
CreatedJan 30, 2023
ResolvedJan 30, 2023
UpdatedFeb 14, 2023