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"

AnswerHub Maintenance

Background maintenance is scheduled to occur between 9 - 11am EDT on Tuesday, May 21. Site operation may be slower than normal during this time and a brief interruption in operation may be observed

How can I play animations strictly from C++?

I see this asked a lot here but never fully answered. I've asked similar questions before. Here are the ground rules:

  • NO use of animation blueprints

  • NO use of animation state machines

  • ONLY C++ calls to play, blend, and manage animation assets

We have: Montage_Play(anim, play speed), and Montage_JumpToSection to skip ahead.

I can't see a way to blend 2 (or more) animation together from C++; alternatively, a way to play a Blend Space (1D or 2D) from C++.

I can't see a way to play an animation into a particular slot from C++ (eg, Upper body or Lower body). Playing a Montage that is not set to slot "Full Body" or "Default" results in not playing at all.

I can't see a way to play an animation to the end and stopping there (i.e. not looping the animation). I could add a bunch of logic to do manage this, but animation systems normally have this in there somewhere.

If it's not possible, I'm fine with that as an answer. If you're curious about why I would not want to use the editor features for these things you can read the following but if you're not curious then you can skip the rest of this paragraph. I've been developing games for many years now and am very comfortable with C++ implementations. IMO, the animation part of the editor is bad for game development. Having two competing and unrelated state machines (one for behavior and one for animation) battling for control over a character is an ill-conceived concept. Both developing complexity in their own unique ways (state machine vs behavior tree or other) while trying to keep it in sync and tracking lines of causality is crazy house. Bugs are invisible, systematic and display emerging behavior (the perfect storm of development pain). It's fine if you're a student trying to learn 3D but for complex professional work, specially dealing with complex animations, it's a non-starter.

Product Version: UE 4.8
Tags:
more ▼

asked Aug 27 '15 at 10:51 PM in C++ Programming

avatar image

rantrod
1.5k 48 47 216

avatar image ScottSpadea Aug 27 '15 at 11:48 PM

handling animations in the editor makes sense, since animations are art assets, and you wouldn't want artists relying on programmers changing and recompiling code, just to add a new hard coded animation reference.

using multiple state machines also makes sense. you really shouldn't have a single state machine controlling an object, unless everything that object can do is mutually exclusive. if you want multiple degrees of freedom, performing multiple tasks at the same time, it makes sense to separate the state into multiple variables. so you should have separate state machine for the camera, navigation, attacks, hitboxes, jumping, stamina, menus, character animations, physics mode, weapons, weapon animations, etc... any functionality you want to trade out independently, should be a separate state.

avatar image rantrod Aug 28 '15 at 01:56 AM

Animation and behavior go hand and hand. If you're doing complex systems of realistic behavior/animation, you don't want artists/designers messing with it. Just a place for them to add the assets (no recompile needed), and expose some parameters for animators and designers to tweak. Any time you save by allowing non-programmers to make changes you pay for ten-fold in development time and bug-hunting.

avatar image ScottSpadea Aug 28 '15 at 04:38 AM

I would suggest having a gameplay programmer who is responsible for event graphs and can also code in c++.

anim graphs, notifies, montages, and state machines are all gameplay programmer jobs. you might be able to hard code those into your engine, but you will lose a lot of the flexibility that gameplay programmers need to iterate on new functionality.

if you want to keep artists from messing up code, tell them not to edit any graphs or data without permission from a gameplay programmer. modelers, animators, and writers should probably not even touch the level editor, unless its just to import their assets. level designers, lighting, and sound designers can place actors into a level, and tweak exposed properties, but if they want a new actor, they should ask the gameplay programmer.

FX artists will need to use the editor to create their content, but they don't need to worry about event graphs, and their assets are cosmetic, so they should not affect external states. they probably don't even need to use the same engine build, they can probably just use a standard build of the editor, without any of your game code.

interface designers also need the editor to make their content, but they should probably be programmers or work in photoshop making mockups. maybe the gameplay programmer should code the menus as well, if they aren't already too busy doing everything else.

or you can go the opposite direction, and hire technical generalists who can make all kinds of things, and work together to spot each others mistakes. you might be trading reliability for speed, but the iterative designs you get out of that process might be more fun. as long as you have a source control versioning system to make file backups, you should be fine just winging it with a talented group you can trust.

avatar image rantrod Aug 28 '15 at 07:24 AM

The features I'm asking about here are available for the other competing engines like Unity and Cryengine. I'm not sure why Unreal would want to shoot for having fewer features or be less complete for advanced development than the others.

The main concern here is that a separate animation system from behavior will create more problems and more work for everyone than it will save; for the reasons already explained. Menus and effects are orthogonal to behavior and are not of concern here. A menu is not trying to change the movement of the character. An effect does not try to change the animation of the character. Those are non-competing systems. Animations are intertwined with behavior. The behavior of throwing a punch and the animation of throwing a punch work together. These are two systems are competing over the character - logic pulling at the character one way, and animation another, the way UE4 does it.

After a while in development you stop worrying about what looks nice and worry more about what gets the job done the quickest with the fewest problems. You start realizing you spend 10% of your time coding and 90% of your time debugging. The animation system in UE4 tries to save you time in the 10% - exactly the wrong place to put your efforts - and adding to the debugging time. After a while you also realize that it's more important to have flexibility in your system than a slick interface. You can't go to a designer and say "we can't do that feature because it doesn't play well with UE4". At the end we're in the Entertainment industry, and producing creative, fun, original content is more important than anything else. I'll take working harder and developing a more impactful game over doing an easy job that produces mediocre products. In my particular case, I believe doing it my way will be both easier and make more impactful products in the long run, and that's what really matters.

avatar image Rezental Aug 29 '15 at 05:51 AM

I'd also like to know how to set and play animations from C++

avatar image rantrod Aug 29 '15 at 06:45 AM

Besides Montage_Play and Montage_JumpToSection, I found something called PlaySlotAnimationAsDynamicMontage in AnimInstance.h which seems promising. You can set the BlendInTime, BlendOutTime, PlayRate, and LoopCount. I'm going to try it soon and will report back if it works for me.

I still need to find a way to blend two animations together strictly from code though.

avatar image r3jonwah85 Sep 14 '15 at 08:02 AM

Any update on this? Used to doing this in Unity and I like having total control in the code.

avatar image rantrod Sep 14 '15 at 11:11 PM

I have posted an answer to the main thread. Take a look and let me know if it helps.

avatar image rantrod Sep 14 '15 at 11:11 PM

I have posted an answer to the main thread. Take a look and let me know if it helps.

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

5 answers: sort voted first

Partial answers:

Playing Blend Spaces from C++:

  • Set a UPROPERTY for your BlendSpace to be set in the Editor:

       UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Anims")
         UBlendSpace1D *BlendSpace;
     
    
  • Play the animation and set the BlendSpace parameter (0-100 how far to mix the anims). In this example, I have a 1D BlendSpace that I'm blending along the 'X' axis (as set in the editor):

      ASkeletalMeshActor *Skel = Cast<ASkeletalMeshActor>(MyActor);
         if (Skel)
         {
             USkeletalMeshComponent *Mesh = Skel->GetSkeletalMeshComponent();
             if (Mesh)
             {
                 Mesh->PlayAnimation(BlendSpace, true);
                 FVector BlendParams(50.0f, 0.0f, 0.0f);
                 Mesh->GetSingleNodeInstance()->SetBlendSpaceInput(BlendParams);
             }
       }
    
    

The example used is with a 1D Blend Space, but it will also work for 2D or 3D blend spaces :)

...

To Play an animation in a slot:

  • As before add the UPROPERTY with the animation sequence to play:

    UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Anims") UAnimSequence *MyAnimSequence;

  • Play the Animation:

       USkeletalMeshComponent *Mesh = MyActor->FindComponentByClass<USkeletalMeshComponent>();
         if (Mesh)
         {
             UAnimInstance *AnimInst = Mesh->GetAnimInstance();
             if (AnimInst)
             {
                 AnimInst->PlaySlotAnimationAsDynamicMontage(MyAnimSequence, TEXT("UpperBody"), 0.1f, 0.1f, 1.0f, 30.0f);
             }
         }
    
    
    

To Play a simple full body animation and stop at the end:

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

Where MyAnimTimer is a float, and PauseMontageTimerHandle is a FTimerHandle.

In MyActor::PauseMontageFunc:

 AnimInst->Montage_Pause();


To Play a simple full body animation and jump ahead to a section. Montage_Play(anim, play speed) and Montage_JumpToSection.

...

To Play an animation additively use the PlaySlotAnimationAsDynamicMontage function as before, into a slot set up like this: https://docs.unrealengine.com/latest/INT/Engine/Animation/AnimHowTo/AdditiveAnimations/index.html

more ▼

answered Sep 14 '15 at 11:10 PM

avatar image

rantrod
1.5k 48 47 216

avatar image Nightmask3 Nov 26 '15 at 12:17 AM

Thanks a ton man!

avatar image KingCole32 Aug 18 '16 at 03:47 AM

Maybe I didn't understand the explanation for the BlendParams, but I got weird results until I used the the metric I'd set my blendspace up with (in this case, passing it angles from -90 to 90). In any case, though, this was a big help.

Did you ever encounter any way of playing a blendspace in a slot or else blending it with the current anim? I've only done it used Animsequences and montages, but not blendspaces or plain anim assets.

avatar image HazzaBui Nov 11 '16 at 04:22 PM

Did you ever figure out the blendspaces in a slot either? I'm struggling with that as well

Cheers,

avatar image rantrod Nov 15 '16 at 12:43 AM

To me it looks like slots are a property of Montages or AnimGraphs so unfortunately I don't think there's a way to play a BlendSpace in a specific slot from code.

avatar image KingCole32 Mar 07 '17 at 06:09 AM

It's been a while since I've looked at this, as I got moved to a different project, but it seems like I remember seeing a method of casting a blendspace as an anim sequence, which can be played from slots...?

Again, the details are foggy and I know I never got it to work properly (I could play a one-off blendspace via code, but it was full-body and, worse, wouldn't return back to the default anim), so I can't make any promises. Might take a look again soon, though.

avatar image wren945 Sep 26 '17 at 12:37 PM

I find that this way montage and blend space are exclusive. You won't be able to play montage in c++ after you play blend space in c++. I tried to call SetAnimationMode, it works. but you lose the blending (transition between the two). Any ideas?

avatar image room101 Nov 08 '17 at 10:50 PM

@wren945 perhaps you can try and have two different states, the default one being your blend space, and transition to the state that handles the montage when needed, and transition back when the montage stopped playingalt text

3-fsm-states.jpg (244.9 kB)
avatar image wren945 Mar 23 '18 at 10:33 AM

Thanks. But aren't we talking about controlling animation "strictly from c++". :)

avatar image wren945 Mar 23 '18 at 10:37 AM

I find the animation transition is mess up if I do it this way. When you switch animation (montage) quickly, they won't transit well. The cross fade just doesn't work. If blend in and blend out time of 2 subsequent animation montages is different, the cross fade is crewed up.

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

Ok, Adding some of the basics that might trip some people up

  • 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) Make sure the Montage's Blend-In, Blend-Out, and Blendout Trigger Timer are set to something low (like 0.01 for Blend-In and out, and -1 for the Trigger). The default settings sometimes causes the animation to not play fully or at all (eg, if your test animations are short).

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

more ▼

answered Nov 27 '15 at 09:32 PM

avatar image

rantrod
1.5k 48 47 216

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

@rantrod This is the best answer so far to play an animation but I'm wondering, why it is so awful hard to do in just C++. Even this example uses blueprints. Each time a programmer asks for plain C++ examples, the response is that blueprints are superior.

For some jobs they are not. I'm developing procedural animation for a different engine and would like to see just a simple -complete and working- example how to play animation in Unreal inside the editor (in Edit mode - not in Play mode).

more ▼

answered Jun 13 '16 at 12:34 AM

avatar image

rotwang
246 13 22 41

avatar image rantrod Jun 13 '16 at 06:37 AM

One thing missing on these responses is how to load the animation in. I use a UPROPERTY because it's easier for me. You can always load in code:

 static ConstructorHelpers::FObjectFinder<UAnimSequence> anim(TEXT("AnimSequence'/Game/Mannequin/Animations/ThirdPersonJump_Start.ThirdPersonJump_Start'"));
      Anim = anim.Object;

(change the sequence path to your own path) or for montage:

 ConstructorHelpers::FObjectFinder<UAnimMontage> anim_move_montage(TEXT("AnimMontage'/Game/TBContent/Animations/forward_montage.forward_montage'"));
          anim_move_montage_ = anim_move_montage.Object;

(Again, change the path to your own path). For both you'd need this in the constructor:

 ConstructorHelpers::FObjectFinder character_model(TEXT("/Game/TBContent/Models/HeroTPP.HeroTPP"));
  
  GetMesh()->SetSkeletalMesh(character_model.Object);

The other thing missing is building the animation blueprint in c++. I have references on how to do this (not on my current computer), but I've never tested it.

That said, the AnimBP as I suggest using it in the main answers is simply a dummy, and the real work is piped through your own c++ code, so I'm not sure if you need to build the AnimBP in c++ even if you're using procedural animations. Unless there's something more sophisticated you want to add in the animBP like IK, the dummy should suffice.

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

Thank you so far, In a simple coding world this would be straight code and would work ( It does not)

 ASkeletalMeshActor* actor = actors[0]; //  any method to get the actor
 UAnimSequence* anim = animations[0]; // any method to get the UAnimationAsset
 
 if (actor && anim)
 {
     USkeletalMeshComponent* mesh = actor->GetSkeletalMeshComponent();
     mesh->SetAnimationMode(EAnimationMode::AnimationSingleNode);
     mesh->SetAnimation(anim);
     mesh->Play(true);
 }




more ▼

answered Aug 19 '16 at 06:34 PM

avatar image

rotwang
246 13 22 41

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

I apologize for barging in, but as this thread comes up in searches, I thought I should chime in with what I learned through trial and error. The example below is not complete, but should help pointing in the right direction, hopefully.

There is a minimum required tinkering with non-C++ blueprints, but in my approach I tried my best to "set it and forget it". If there are better ways, please share :)

This is how my montage looks like, just two empty slots, I handle their population through C++ alt text

this is how my anim graph in my custom animation instance looks like alt text

Inside each state machine I connected a dummy empty state to the entry point, not shown in this picture, but you get the gist of it.

This is my C++ code snippet to handle fetching animation sequences on the fly and assign them to the montage slots. please note that I'm using some custom functions I wrote that are not shown in the code below

 for (int32 l = 0; l < oCreature->AnimMontage->SlotAnimTracks.Num(); l++)
             {
                 FSlotAnimationTrack slot = oCreature->AnimMontage->SlotAnimTracks[l];
                 if (slot.SlotName.ToString().Contains("LowerBody"))
                 {
                     FAnimSegment NewSegment;
                     NewSegment.AnimReference = oCreature->AnimSequence;
                     NewSegment.AnimStartTime = animationListList.AnimationList[j].StartTime;
                     NewSegment.AnimEndTime = oCreature->AnimSequence->SequenceLength;
                     NewSegment.AnimPlayRate = animationListList.AnimationList[j].Speed;
                     NewSegment.LoopingCount = 1;
                     NewSegment.StartPos = animationListList.AnimationList[j].StartOffset;
 
                     slot.AnimTrack.AnimSegments.Add(NewSegment);
 
                     oCreature->AnimMontage->SlotAnimTracks[l] = slot;
                     break;
                 }
             }
         }
     }
 }

as I mentioned, the example above is not either complete or fully functional out-of-the-box, but hopefully should help...

montage.jpg (100.5 kB)
animgraph.jpg (168.5 kB)
more ▼

answered Sep 10 '16 at 12:07 AM

avatar image

room101
11 1 5 8

avatar image fdcumt May 01 '19 at 12:39 AM

hi @room101, thanks for your answer, but I still have some puzzled, where the code be called, and what the type oCreature, now I use the UE4.22.

(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