x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Office Holiday

Epic Games' offices will be on holiday from June 22nd to July 7th. During this period support will be limited. Our offices will reopen on Monday, July 8th. 

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.

Product Version: UE 4.10
Tags:
more ▼

asked Nov 23 '15 at 01:45 AM in C++ Programming

avatar image

Lolunknown
26 1 2 3

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

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: https://answers.unrealengine.com/questions/292345/how-can-i-play-animations-strictly-from-c.html

more ▼

answered Nov 24 '15 at 04:08 AM

avatar image

rantrod
1.5k 49 47 216

avatar image Lolunknown Nov 25 '15 at 12:51 AM

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?

avatar image Matthew J Nov 25 '15 at 05:12 PM

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.

avatar image rantrod Nov 25 '15 at 09:19 PM

Sorry, there was an extra period in the link but it's fixed now (Thanks to matthew_clark!). 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.

avatar image Lolunknown Nov 26 '15 at 09:35 AM

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.

avatar image rantrod Nov 26 '15 at 10:42 PM

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?

avatar image Lolunknown Nov 27 '15 at 01:01 AM

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::Red, 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);
 }

avatar image rantrod Nov 27 '15 at 09:28 PM

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). alt text

  • 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) alt text

    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 MyCMontageObj(TEXT("/Game/ThirdPerson/Animations/ThirdPersonWalk_Montage")); MyCMontage = MyCMontageObj.Object;

    c) Play the montage as before

montageslot.png (376.9 kB)
animbpslot.png (83.5 kB)
avatar image Lolunknown Nov 28 '15 at 09:20 AM

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.

avatar image rantrod Nov 28 '15 at 11:29 AM

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?

avatar image Lolunknown Nov 30 '15 at 01:49 AM

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.

avatar image rantrod Nov 30 '15 at 07:34 AM

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.

avatar image Lolunknown Nov 30 '15 at 08:57 AM

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.

avatar image rantrod Nov 30 '15 at 09:27 AM

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.

avatar image Shmoopy1701 Sep 26 '18 at 02:25 PM

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()

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question