Description

Calling SetKeyTime in iterating KeyHandlesToIndices array can modify the array order, so it breaks the iterator.
Perhaps ShiftCurve also has the same problem.
Here is a work around:

void FIndexedCurve::ScaleCurve(float ScaleOrigin, float ScaleFactor, const TSet<FKeyHandle>& KeyHandles)
{
	if (KeyHandles.Num() != 0)
	{
#if 0
		for (auto It = KeyHandlesToIndices.CreateConstIterator(); It; ++It)
		{
			const FKeyHandle& KeyHandle = *It;
			if (KeyHandles.Contains(KeyHandle))
			{
				SetKeyTime(KeyHandle, (GetKeyTime(KeyHandle) - ScaleOrigin) * ScaleFactor + ScaleOrigin);
			}
		}
	}
#else //workaround
		for (auto It = KeyHandles.CreateConstIterator(); It; ++It)
		{
			const FKeyHandle& KeyHandle = *It;
			if (KeyHandlesToIndices.Find(KeyHandle)!=nullptr)
			{
				SetKeyTime(KeyHandle, (GetKeyTime(KeyHandle) - ScaleOrigin) * ScaleFactor + ScaleOrigin);
			}
		}
	}
#endif
}
Steps to Reproduce
  1. compile and run following code
    // Some comments here
    	FRichCurve richCurve;
    	richCurve.AddKey(1.41250002f, 0.f);
    	richCurve.AddKey(1.65260422f, 1.f);
    	//
    	richCurve.ScaleCurve(0.f, 1.19417477f);
    	//
    	int32 i = 0;
    	for (auto&& key : richCurve.GetCopyOfKeys())
    	{
    		UE_LOG(LogTemp, Log, 
    			TEXT("[key%d]time=%f,value=%f"),
    			i++, key.Time, key.Value);
    	}
    

Result:

LogTemp: [key0]time=1.652604,value=1.000000
LogTemp: [key1]time=2.014300,value=0.000000

Values are swapped.

Expected Result:

LogTemp: [key0]time=1.652604,value=0.000000
LogTemp: [key1]time=2.014300,value=1.000000

Have Comments or More Details?

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

0
Login to Vote

Unresolved
ComponentUE - Anim - Runtime
Affects Versions5.4
Target Fix5.6
CreatedFeb 13, 2025
UpdatedMar 3, 2025
View Jira Issue