Is there any way to modify bone tracks with C++?

I know AnimModfiers are great at automating some processes like adding notifies or sync markers, but I want to modify the animation poses directly. I read through the document of AnimModifier, but it seems there is no such function that directly modifies the animation poses (bone’s keyframe).

Add “add new raw track” from C++ Api.
I think this function UAnimSequence::AddNewRawTrack | Unreal Engine Documentation
That works for me. Be careful with new transforms arrays to replace raw track data, these lenght should be equal to anim frames count, otherwise engine crash.

Thanks for your reply. I took a look at the node you mentioned but seems like that node is deprecated in UE5-EA. After reading the source code, especially those functions in the AnimBlueprintLibarary, I found UE5 introduced a new class to handle modifying animations. That class is called AnimDataController. Now with that new class, we can modify bone tracks by using

AnimSequence->GetController()->AddBoneTrack()

and

AnimSequence->GetController()->SetBoneTrackKeys()

Have you tried it? In my case, SetBoneTrackKeys causes crash with “Ran out of memory” error regardless of how many keys I apply.

UPD. Never mind, it was my AnimSequence asset created with default 60,000 sample rate instead of 60.

Have you found a way to create the AnimSequence with 30/60 samples instead of 60000 ? in UE5 no matter what I do is creates it with 60000
Thanks.

Yes.

UObject* NewObject = AssetTools.CreateAsset(
	NewAssetName,
	InAssetPath,
	UAnimSequence::StaticClass(), nullptr /*, factory*/);

if (NewObject)
{
	if (UAnimSequence* NewSeq = Cast<UAnimSequence>(NewObject))
	{
		const int32 UseFrameRate = 30;

		// Notify asset registry
		FAssetRegistryModule::AssetCreated(NewSeq);

		// Set skeleton
		NewSeq->ResetAnimation();
		NewSeq->SetSkeleton(Skel);
		NewSeq->ImportFileFramerate = (float)UseFrameRate;
		NewSeq->ImportResampleFramerate = UseFrameRate;

		// Initialize data model
		IAnimationDataController& Controller = NewSeq->GetController();
		Controller.OpenBracket(LOCTEXT("InitializeAnimation", "Initialize New Anim Sequence"));
		{
			// This line is to set actual frame rate
			Controller.SetFrameRate(FFrameRate(UseFrameRate, 1), true);

			Controller.SetPlayLength(RawCurvesAnim->Duration, true);
			Controller.NotifyPopulated();
		}
		Controller.CloseBracket();
	}
}
2 Likes

Worked like a charm, thank you boss you’re a life saver. :100: :100:

Wow thank you for posting this, I was having the same issue where my 1 second clip was 60000 frames.

For people from the future, you will get a LOCTEXT issue if (like me) you didn’t use #if WITH_EDITOR as discussed in this thread.