<style>.lazy{display:none}</style> Skip to main content

Unreal Engine C++ Fundamentals – Override UAnimInstance

By January 12, 2019Development, Tutorial, Unreal

Hey guys,

This week we continue on with fundamentals, this time going over how to override UAnimInstance in order to have more control and tighter C++ integration with our other classes.

You can find the source code for this video on the GitHub project page.

We looked at UAnimInstance before, have you gone senile !

Last time we looked at UAnimInstance was in the context of using it to access montage controls to give us finer control over our animation playback. This time we are going to move the Event Graph definition from a blue print driven anim instance and migrate all that functionality into our own C++ class.

 

Why bother rolling our own ? Blueprints are easy !

We can certainly use blueprints for all this work but having low level c++ access gives us a lot of control over our animation settings.

For example if you want to extend your animation system to support Inverse Kinematics, it becomes much simpler to compress that logic via convenient c++ method definitions rather than having to draw out a spaghetti bowl full of blue print nodes that make it hard to debug and troubleshoot.

 

Let’s take a look at some of the methods involved in this process.

virtual void NativeInitializeAnimation() override;

virtual void NativeUpdateAnimation(float DeltaTimeX) override;

NativeInitializeAnimation allows us to handle initialization of various properties on our animation instance and works similar to the InitializeComponent or BeginPlay methods on the Actor.

NativeUpdateAnimation on the other hand, works similar to the Tick functions and updates the properties for the animation blend spaces to process.

 

Interesting … I would like to subscribe to your newsletter

Now let’s take a look at the actual implementation details.

.h

UCLASS()
class UE4FUNDAMENTALS06_API UPlayerAnimInstance : public UAnimInstance
{
  GENERATED_BODY()
public:
  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Animation")
    bool IsInAir;

  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Animation")
    bool IsAnimationBlended;

  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Animation")
    float Speed;

public:
  UPlayerAnimInstance();

  virtual void NativeInitializeAnimation() override;

  virtual void NativeUpdateAnimation(float DeltaTimeX) override;

private:
  APawn* Owner;
};

.cpp

void UPlayerAnimInstance::NativeInitializeAnimation()
{
  Super::NativeInitializeAnimation();

  // cache the pawn
  Owner = TryGetPawnOwner();
}

void UPlayerAnimInstance::NativeUpdateAnimation(float DeltaTimeX)
{
  Super::NativeUpdateAnimation(DeltaTimeX);

  // double check our pointers make sure nothing is empty
  if (!Owner)
  {
    return;
  }

  if (Owner->IsA(AUE4Fundamentals06Character::StaticClass()))
  {
    AUE4Fundamentals06Character* PlayerCharacter = Cast<AUE4Fundamentals06Character>(Owner);
    // again check pointers
    if (PlayerCharacter)
    {
      IsInAir = PlayerCharacter->GetMovementComponent()->IsFalling();
      IsAnimationBlended = PlayerCharacter->GetIsAnimationBlended();
      Speed = PlayerCharacter->GetVelocity().Size();

      GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, "IsInAir: " + FString(IsInAir ? "true" : "false"));
      GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, "IsAnimationBlended: " + FString(IsAnimationBlended ? "true" : "false"));
      GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, "Speed: " + FString::SanitizeFloat(Speed));
    }
  }
}

As you can see from our code, there is really not much to it.

Outside of overriding the methods you want to take control of the rest comes down how much or how little animation data you want to expose to the blueprint.

The only real major point of complication is to ensure that the pawn attached to this animation instance is correctly cast before you get at it’s details.

With your own anim instance you can now start compartmentalizing your complicated logic, handle various player types against different blend space behaviors and generally modify your animation to suit your game.

For more details check out the links below:

Leave a Reply