Animations with c++ NOT BLUEPRINTS

Hello. As the title states, I’m looking for a way to play animations properly through c++ programming NOT BLUEPRINTS. Currently I am using the GetMesh()->PlayAnimation method but it only plays after the character has stopped moving and doesn’t animate during or depending where I’m calling that function, it doesn’t animate at all. Is there a way to do fluent animations or fix this problem WITHOUT BLUEPRINTS? I’ve tried Googling and looking through the Unreal tutorials, but they’re using Blueprints even when labled as “C++ Programming” and I’ve come across nothing of help. Thanks in advance.

Support for playing animations from c++ is poor. Characters compete with it, as you mentioned, and not all animation features are available. I believe montages win over Character anims. See if the answer here helps: How can I play animations strictly from C++? - Character & Animation - Epic Developer Community Forums

Thanks for the reply, but the link is broken. I think i know what you’re referring to and I’ve looked over that discussion.

So I’ve been tinkering with it and I made an Anim Montage in the editor and made an Animation Blueprint and linked them. Now when I call Montage_Play in code it only plays AFTER my character has moved even though i’m calling it in the movement code. If I call it on button press it plays it only once when i first press the button. I’ve tried using a bool, but when checking if the bool is true in Tick and then playing it if it is true, it doesn’t play. I don’t understand what I’m doing wrong. Any insight?

Hello Lolunknown,

I’m not familiar on the topic but I just edited rantrod’s answer as the link was only malfunctioning due to the period at the end. Please try checking it again as it may be helpful.

Sorry, there was an extra period in the link but it’s fixed now (Thanks to !). If the Character code is automatically animating your character, then either use Pawn as your base class or create an AnimBP with a State Machine that just has an Idle in it, and have your character use it.

If I set an animation state machine, then that would be using blueprints and it would just always play, which is not what I want. I want to use c++ to play an animation but when I call Montage_Play on the function that the key press is using it doesn’t play and I don’t know why. I have the Montage set up and the AnimationBP.

When I have an animation state machine with just idle, it does play the idle, but that idle is overwritten by Montage_Play. When Montage_Play is done, it’ll go back to that Idle. At least that’s what happened when I tried it.

If you don’t want any animation to play unless you call it in C++, then you can try leaving the AnimBP blank for the character or derive from Pawn instead. I haven’t tried these options though.

Can you share the code where you are checking for a key press? Did you set a breakpoint on the Montage_Play function to make sure it’s being called? Is the keypress set up as an event or are you checking on a Tick?

I don’t have the code on hand, but I’m using the characters pre-defined input function and calling key presses in there. I’ve put Montage_Play in Axis binds and Action binds and it didn’t work. The movement is being changed OnTick and when I call it within the if check, it plays the animation after I’m done moving. I can post code when I’m home, but it’s just the standard input function the character class gives you.

EDIT: Here’s the code. The functions that the input keys are calling is where i put the animation but it doesn’t work in either of them.

// Called every frame
void ALichDota::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

	//GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::, FString::Printf(TEXT("Moving: %s"), moving ? TEXT("True") : TEXT("False")));

	if (!Move_Vec.IsZero()) {
		
		Move_Vec = Move_Vec.SafeNormal() * 100.0f;
		FVector New_Loc = GetActorLocation();
		New_Loc += GetActorForwardVector() * Move_Vec.X * DeltaTime;
		New_Loc += GetActorRightVector() * Move_Vec.Y * DeltaTime;
		
		SetActorLocation(New_Loc);
		//GetMesh()->GetAnimInstance()->Montage_Play(Anim, 1.0f);
	}
}

// Called to bind functionality to input
void ALichDota::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
	Super::SetupPlayerInputComponent(InputComponent);

	InputComponent->BindAxis("Move_X", this, &ALichDota::Move_X);
	InputComponent->BindAxis("Move_Y", this, &ALichDota::Move_Y);

	InputComponent->BindAction("Test", IE_Pressed, this, &ALichDota::Test);
	InputComponent->BindAction("Test2", IE_Released, this, &ALichDota::Test_Two);
}

Ok, going to make some corrections and going over basics:

  • You need an animation blueprint to be present.
  • In the animation blueprint you need a slot node going into the final pose. The default one is fine (DefaultGroup.DefaultSlot).

  • If you want your character to default to ‘Idle’ if nothing is happening, you can connect “Play Idle” to the default slot but it’s not necessary.

  • In code you can play a montage into that default slot:

    a) You need a UPROPERTY where you can specify the Montage:

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Anim)
    UAnimMontage *MyMontage;

    b) In the Montage make sure it plays into the slot you specified (DefaultGroup.DefaultSlot is the default which should be fine)

c) Play the Montage:

if (MyMontage->IsValidLowLevel())
{
	USkeletalMeshComponent *Mesh = GetMesh();
	if (Mesh)
	{
		UAnimInstance *AnimInst = Mesh->GetAnimInstance();
		if (AnimInst)
		{
			AnimInst->Montage_Play(MyMontage);
		}
	}
}

OR

a) Declare your montage variable in your header file:

UPROPERTY() // not absolutely necessary but highly recommended
UAnimMontage *MyCMontage;

b) In the constructor, load the montage:

static ConstructorHelpers::FObjectFinder<UAnimMontage> MyCMontageObj(TEXT("/Game/ThirdPerson/Animations/ThirdPersonWalk_Montage"));
MyCMontage = MyCMontageObj.Object;

c) Play the montage as before

Sorry, I thought that loading the montage and the animBP being right were implied, my fault. I should’ve posted all the code i had.
This is in my .h:

UPROPERTY() UAnimMontage *Anim;

This is in my .cpp:

static ConstructorHelpers::FObjectFinder anim(TEXT("Float'/Game/StarterContent/Imports/Lich/Float.Float'")); Anim = anim.Object;

In my Animation Blueprint i just have my slot connecting to the Result. So everything you’ve mentioned is done. But when I call Montage_Play in the function my button press is calling, it doesn’t play, as mentioned before.

hmm, In your Montage, do you have the Blend In, and Blend Out times to something low, like 0.01? Blend Out Trigger Timer to -1? When the blend parameters are high or the animation is short, they can end up cutting off the animation completely. Did you verify the Montage_Play is actually getting called?

I got it working. I put a break point, ran the game from Visual Studio, closed the new instance it opened and then compiled and played and it worked. But i have a question, how do I add multiple animations to 1 animBP? Just different sections in the montage? or can I hook up multiple slots to the Result in AnimBP

I’ll update it after i’ve run some tests to make sure it’s working properly.

You can call Montage_Play for any number of animations without having to modify the AnimBP. When one anim is about done, just call Montage_Play for the next, taking into account time for blending out and into the next animation.

You can also have a Montage with multiple animations and use Montage_JumpToSection to switch between them, however, when jumping I don’t believe you get any blending so I think it’s better to call different Montages if you want one animation to blend to the next.

That said, for people using the AnimBP to play animations for their characters, they set an animation state machine to switch between the different animations. The animation state machine then leads to the final pose.

I can’t access a State Machine in code. The main priority is to use c++ without blueprints, but for animations there’s no other way without an AnimBP (GetMesh()->PlayAnimation didn’t work at all when set up right.).

I figured out how to set up the animations in the AnimBP, but now i’m having trouble accessing the Notify boolean used to stop a looping animation, in code. I suppose i could just have IE_Released inputs that call an idle animation, it would be easier.

If you want to continue in C++ only, then all you need in the AnimBP is the slot connected to the final pose and nothing else.

I believe calling Montage_Play from C++ doesn’t loop the animations. The function returns the length of the animation in seconds so you can setup the next animation to play when the current one is done.

MyAnimTimer = AnimInstance->Montage_Play(MyMontage);
 GetWorldTimerManager().SetTimer(EndMontageTimerHandle, this, &MyActor::EndMontageFunc, MyAnimTimer, false);

Or just set your own state machine in C++ and keep track of timers in your tick function.

Trying to follow this. The animation attempts to play but Unreal gives this error:

“Currently in Animation Blueprint mode. Please change AnimationMode to Use Animation Asset”

EDIT: solved

  • if a skeletal mesh is playing an animation montage, and you call mesh->IsPlaying() it fails and spits that warning
  • you have to call mesh->GetAnimInstance()->Montage_GetIsStopped() or Montage_GetIsPlaying()

Question is posted in 2015, I’m still looking for answer

1 Like

Looking a lot like 2022 now, still no answer.