Download

How to setup and play animation strictly using c++

Hi guys!

i want to sctrictly play a idle animation using c++ only …
currently i m doing like this…

char.h

UCLASS()
class TREBUCKET_1_API Atb_enemyCharacter : public ACharacter
{
GENERATED_BODY()

public:
// Sets default values for this character’s properties
Atb_enemyCharacter();

UAnimSequence* IdleAnim;
USkeleton* meshSkeleton;

UMaterialInterface* mansQmat;

protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;

public:
// Called every frame
virtual void Tick(float DeltaTime) override;

// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

};

char.cpp

// Sets default values
Atb_enemyCharacter::Atb_enemyCharacter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don’t need it.
PrimaryActorTick.bCanEverTick = true;

GetCapsuleComponent()->SetupAttachment(RootComponent);
GetCapsuleComponent()->SetCapsuleHalfHeight(96.f);
GetCapsuleComponent()->SetCapsuleRadius(42.f);


static ConstructorHelpers::FObjectFinder<USkeletalMesh> skMeshAsset(TEXT("/Game/TB_1/Mannequin/Character/Mesh/SK_Mannequin.SK_Mannequin"));

if (skMeshAsset.Succeeded())
{

    GetMesh()->SetSkeletalMesh(skMeshAsset.Object);
    GetMesh()->SetRelativeLocation(FVector(0.f, 0.f, -97.f));
    GetMesh()->SetRelativeRotation(FRotator(0.f, 270.f, 0.f));
    GetMesh()->SetVisibility(true, true);
    GetMesh()->VisibilityBasedAnimTickOption = EVisibilityBasedAnimTickOption::AlwaysTickPoseAndRefreshBones;
    GetMesh()->SetAnimationMode(EAnimationMode::AnimationSingleNode);
}

meshSkeleton = CreateDefaultSubobject<USkeleton>(TEXT("meshskeleton_1"));

static ConstructorHelpers::FObjectFinder<USkeleton> skeletonObj(TEXT("/Game/TB_1/Mannequin/Character/Mesh/UE4_Mannequin_Skeleton.UE4_Mannequin_Skeleton"));

if (skeletonObj.Succeeded())
{
    meshSkeleton = skeletonObj.Object;
}

static ConstructorHelpers::FObjectFinder<UAnimSequence> animObj(TEXT("/Game/TB_1/Mannequin/Animations/ThirdPersonIdle.ThirdPersonIdle"));
IdleAnim = animObj.Object;
IdleAnim->SetSkeleton(meshSkeleton);

mansQmat = CreateDefaultSubobject<UMaterial>(TEXT("manQmat_1"));

static ConstructorHelpers::FObjectFinder<UMaterial> skMatAsset(TEXT("/Game/TB_1/Mannequin/Character/Materials/M_UE4Man_Body.M_UE4Man_Body"));

if (skMatAsset.Succeeded())
{
    //skMesh->SetMaterial(0, mansQmat);
    GetMesh()->SetMaterial(0, mansQmat);
}

}

// Called every frame
void Atb_enemyCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//GetMesh()->SetAnimation(IdleAnim);

if (IdleAnim->IsValidToPlay())
{
    GEngine->AddOnScreenDebugMessage(-1, 15.f, FColor::Red, TEXT("PlayAnimation"));

    GetMesh()->SetPlayRate(0.5f);
    GetMesh()->PlayAnimation(IdleAnim, true);

}

}

@vivek599 Just looking over quickly - not sure it matters - but isn’t the tick function calling PlayAnimation every frame? Not sure if that will cause it to play from the start frame - maybe try just calling Play once… I typically use AnimGraph myself so not sure but thought I would mention

Unless you make some changes to engine source and make public a few protected functions, you cannot setup anim state machines and manipulate states in C++.

You can run the exec graph in C++, but not the state machine graph.

okay i moved the playanimation to begin play in it is now working… thank you…

One more thiing i want to ask… since we are talking about playing animation … how do we get anim end event in c++ , which function to override…

if i remember correctly there used to be a OnAnimEnd(…) function in UE3… i am not aware of that in UE4 however…

any body to comment on OnAnimEnd(…) …

It looks like you will have to override the methods from AnimNotify.h if you want to get animation end notifies purely in C++ … check out this forum post where an Epic staff member commented on it. Is it possible to run C++ code from an animation Notify? - Unreal Engine Forums

@vivek599 Are you able to play animations in reverse like this?

Asking because we are doing animation control C++ only and have to use montages to get any sort of pause or play in reverse functionality…

by doing like this… im able to play in reverse without montage…

GetMesh()->SetAnimation(IdleAnim);
GetMesh()->SetPlayRate(-0.5f);
GetMesh()->Play(true);

note the negative sign…

and this…

http://jollymonsterstudio.com/2018/12/10/unreal-engine-c-fundamentals-uanimnotify-uanimnotifystate/

Oh nice. How about pausing? Like say I need to pause the animation at .6 of the way through, then resume?

I would ditch all montage if that is possible in C++ on regular animations.

If you work like that then you lose animation blending capabilities. At least use a blending space asset…

It is helpful post. Thanks for sharing