[tiny feature request] Get Length for Animation Sequence

Currently I can’t check animation length throu BP.
It would be nice to add node “Get Length” for animation :slight_smile:

Hey ,

Thank you very much for your idea on how to improve UE4. I have submitted your feature request to our developers. If you need to reference this request in the future, please refer to: UE-11947.

Cheers!

+1 I’m looking for the same thing, i guess it’s not available yet? :slight_smile:

Edit: And because i need to calculate few things based on animation length, it also would be nice to have possibility to get Rate Scale of an animation sequence - because if animation length is 1s and we set Rate Scale to e.g. 0.5, the real length will be 2s, so we would need to include Rate Scale.

Hey,

In the blueprint editor, ‘Get Length’ is a function within the Animation category. You may need to take off the context sensitivity.

I’ve found it, but i needed to change my variable type from Anim Sequence to Anim Single Node Instance. Thanks!

I needed the same thing and couldn’t wait for someone else to update it. For those of you who are brave enough to modify the engine, here’s the changes you need to make to get the animation length to be added as an output to your blueprint node:

AnimSingleNodeInstance.CPP:

float UAnimSingleNodeInstance::GetLength()
{
	if ((CurrentAsset != NULL))
	{
		if (UBlendSpace* BlendSpace = Cast<UBlendSpace>(CurrentAsset))
		{
			return BlendSpace->AnimLength;
		}
		else if (UAnimSequenceBase* SequenceBase = Cast<UAnimSequenceBase>(CurrentAsset))
		{
			//this is wrong because it doesn't take into account play rate and play position.
			//return SequenceBase->SequenceLength;

			//Note: not accounting for the play position. Don't know if there are any dependencies on this.
			//might want to create a separate "play length" method.
			//sample: 5 secs * 2x play rate = 5/2 = 2.5s; 5 secs * 0.5x = 10 seconds.
			return (SequenceBase->SequenceLength / SequenceBase->RateScale));
		}
	}	

	return 0.f;
}

SkeletonMeshComponent.H:

/**
	* Plays the selected animation.
	* @param NewAnimToPlay The animation asset you want to play on the skel mesh
	* @param bLooping Whether you want to loop the animation or not
	* @return The duration of the animation play time.
	*/
	UFUNCTION(BlueprintCallable, Category="Components|SkeletalMesh")
	float PlayAnimation(class UAnimationAsset* NewAnimToPlay, bool bLooping);

/**
	* Plays the current animation.
	* @param bLooping Whether you want to loop the animation or not
	* @return The duration of the animation play time.
	*/
	UFUNCTION(BlueprintCallable, Category="Components|SkeletalMesh")
	float Play(bool bLooping);

SkeletonMeshComponent.cpp

float USkeletalMeshComponent::PlayAnimation(class UAnimationAsset* NewAnimToPlay, bool bLooping)
{
	SetAnimationMode(EAnimationMode::AnimationSingleNode);
	SetAnimation(NewAnimToPlay);
	return Play(bLooping);
}
float USkeletalMeshComponent::Play(bool bLooping)
{
	UAnimSingleNodeInstance* SingleNodeInstance = GetSingleNodeInstance();
	if (SingleNodeInstance)
	{
		SingleNodeInstance->bPlaying = true;
		SingleNodeInstance->bLooping = bLooping;
		return SingleNodeInstance->GetLength();
	}
	else if( AnimScriptInstance != NULL )
	{
		UE_LOG(LogAnimation, Warning, TEXT("Currently in Animation Blueprint mode. Please change AnimationMode to Use Animation Asset"));
		
	}
	return 0.f;
}

I’d add it to the github source, but I don’t know how to commit my changes to the master repo.

Considering the age of this topic, I am not sure whether you are still interested in a solution. Mind, I am not the most skilled programmer out there, so there are possibly better solutions. If you are willing to make a blueprint function library using C++, please do the following;

If you don’t have your own function library yet, make a new C++ class in the engine. I think deriving from object is enough.

Then, in your .h file, add the following function (make sure a “public:” precedes it, otherwise the compiler will complain);

UFUNCTION(BlueprintCallable, Category = "Animation", Meta = (DisplayName = "Get Animation Sequence Length"))
	static void GetAnimSequenceLength(UAnimSequence* AnimSequence, float& AnimationLength);

In your .cpp, add the following:

void UMyBlueprintFunctionLibrary::GetAnimSequenceLength(UAnimSequence* AnimSequence, float& AnimationLength)
{
	AnimationLength = 0.f;

	if (AnimSequence)
	{
		if (AnimSequence->RateScale != 0)
		{
			AnimationLength = AnimSequence->SequenceLength / AnimSequence->RateScale;
		}
	}
}

With this, you should be able to call on the length of whatever animation sequence you feed into the function. It also takes into account RateScale (since SequenceLength is the original imported length).

If there are any issues, let me know. Not all that familiar with helping people out with c++ and everything, so there may be mistakes in my explanation.

Thank you, I don’t know about C++ but it help me to create my first CPP function, just changed UMyBlueprintFunctionLibrary in the .cpp to AMyBlueprintFunctionLibrary for no compile errors.

It appears that in 4.9.1 (and perhaps earlier versions, but not sure), there’s a GetPlayLength node that can be used in the Animation Blueprint’s EventGraph. The Target is an Anim Sequence Base, and the Return Value is the duration of the animation.

The tooltip for the GetPlayLength node says it returns the length of a Montage, but I use it on Anim Sequences directly just fine - no Montages needed.

Unfortunately, it doesn’t appear to take the Rate Scale into account, which is too bad.