Download

Is it possible to run C++ code from an animation Notify?

I have a Combat component on my ACharacter which contains all the code to run sweep tests around a certain location to check for enemies, and I have my prototype punch animation in Persona, but the only Notifies I’m seeing are for particles and sound effects- is there a super-simple way I can call my Attack(FVector hitboxCenter) on a specific frame and pass it a specific bone/socket’s FVector as an argument?

You can create a subclass of UAnimNotify (or UAnimNotifyState) in C++ and override Notify (or NotifyBegin/NotifyTick/NotifyEnd) to do whatever you want. For one-offs without a payload, you can also just expose the C++ method in your UAnimInstance subclass, and call it from a BP AnimNotify (Add Notify…New Notify, then implement that in the event graph to call your C++ function).

Cheers,
Michael Noland

So that is just incredibly awesome, thank you!!

I’m curious, for events that need to be frame-specific, like setting some bool bCanMove false for five very specific frames of an attack, would your recommendation be to use a single notify setting the bool to false during NotifyBegin and true on NotifyEnd, or to use two separate notifies to achieve the same effect?

I’d use an AnimNotifyState, as it has an explicit duration that you can see in the animation editor and it ensures that the events are all generated correctly/in the proper order, I think even if you skip time into the middle of the range.

For example, Fortnite uses exactly this pattern to tell the pawn owner during NotifyBegin and NotifyEnd, calling the same method with true in begin and false in end, to enable/disable some things.

Cheers,
Michael Noland

That’s perfect! Thank you very much for the advice :slight_smile:

Quick follow-up if you don’t mind- is there any obvious reason why the following isn’t working? The notify is exposed in Persona, I can set it to a range of frames and edit the UPROPERTY-ed variables in the editor, but the debug message in the notify doesn’t fire on the designated frame:

.h:



      UCLASS()
      class LEARNINGPROJECT_API UHitframeNotify : public UAnimNotify
      {
         GENERATED_BODY()
     
     public: 
         UPROPERTY(EditAnywhere)
         FVector testVector;
     
         void Recieved_NotifyTick();
         void Recieved_NotifyStart();
         void Recieved_NotifyEnd();
     
     };
     

.cpp:



      void UHitframeNotifyState::Recieved_NotifyStart(){
          GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "Notification!");
      }

Heya, there are a couple of issues here.

First, you’ve derived from the wrong class. UAnimNotify has only Notify, while UAnimNotifyState has NotifyBegin, NotifyTick, and NotifyEnd. Note: When you override methods, you can put the override keyword at the end of the function declaration, and the compiler will let you know if you have a typo or the base class got refactored (saying something like overriding a method that doesn’t exist in the parent class). This is really helpful in keeping your code working in the long term and helps catch issues like this quickly.

Second, you’re using the names of the Blueprint events rather than the C++ methods that call those events. You’ll want to use NotifyBegin/NotifyEnd rather than Recieved_*.

Cheers,
Michael Noland

That is a darn handy trick with override- you are absolutely on the money with the comment about using the blueprint events instead of the C++ function- taking a look at UAnimNotify.h cleared up a lot. It all works now, thank you so much! :slight_smile:

Thanks Noland, u helped me a lot!