ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Unreal] 언리얼 Anim Notify State C++로 작성해보기
    쾌락없는 책임 (공부)/Unreal 2023. 4. 27. 14:06
    반응형

    개요

    언리얼에서 Montage 를 사용하게 되면 애니메이션의 타이밍에 무언가를 호출하기 위해 Notify를 사용하는 경우가 있습니다. 이런 Notify는 일단 단일, 즉 1번 불리게 되는 기능이고 특정 구간동안 함수를 호출하고 싶다라고 한다면 Notify State를 사용하면 됩니다.

    BP로 만드는거야 여기저기 자료가 많이 있을 것 같고, 그래서 C++로 이를 작성하는 방법을 간단하게 적어보겠습니다.

     

     

    Notify State cpp 함수

    일단 cpp 함수를 만들면서 Notify State를 상속받는 함수를 제작해야 합니다.

    여기서 AnimNotifyState를 상속받았다면 재정의 가능한 함수 3개를 보시면 됩니다. NotifyBegin, NotifyTick, NotifyEnd 입니다. 이름을 들어보면 딱 알 수 있는데 각각 Notify State가 시작될 때, 하는 중에, 끝날 때 불리는 함수 입니다.

    대충 타임라인에서 이런 식으로 불리게 된다는 것이죠.

     

    virtual void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration, const FAnimNotifyEventReference& EventReference) override;
    virtual void NotifyTick(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float FrameDeltaTime, const FAnimNotifyEventReference& EventReference) override;
    virtual void NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, const FAnimNotifyEventReference& EventReference) override;

     

    이것들을 재정의할 떄 주의할 점은 언리얼 버전에 따라서 사용되지 않는 함수가 있을 수 있습니다. 하위호환을 위해서 남아는 있는 것으로 보이는데 이를 잘 확인해서 바른 함수를 사용할 수 있도록 합시다.

     

    UE_DEPRECATED(5.0, "This function is deprecated. Use the other NotifyBegin instead.")
    virtual void NotifyBegin(USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation, float TotalDuration);
    UE_DEPRECATED(5.0, "This function is deprecated. Use the other NotifyTick instead.")
    virtual void NotifyTick(USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation, float FrameDeltaTime);
    UE_DEPRECATED(5.0, "This function is deprecated. Use the other NotifyEnd instead.")
    virtual void NotifyEnd(USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation);

     

    이런식으로 인자를 받는 함수들의 경우 5.0 이후에서는 이 함수를 사용하시면 안되는 것으로 보이네요.

     

     

    Notify State 함수들 활용하기

    void UEnableMovementNotifyState::NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
    	float TotalDuration, const FAnimNotifyEventReference& EventReference)
    {
    	Super::NotifyBegin(MeshComp, Animation, TotalDuration, EventReference);
    	MeshComp->GetAnimInstance()->RootMotionMode = ERootMotionMode::IgnoreRootMotion;
    }
    
    void UEnableMovementNotifyState::NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
    	const FAnimNotifyEventReference& EventReference)
    {
    	Super::NotifyEnd(MeshComp, Animation, EventReference);
    	MeshComp->GetAnimInstance()->RootMotionMode = ERootMotionMode::RootMotionFromMontagesOnly;
    }

    인자로 사용되는 스켈레탈 메쉬 컴포넌트와 그 외 다른 것들을 인자로 주기 때문에 이를 활용해서 사용하면 됩니다.

    const auto MeshOwnerActor = MeshComp->GetOwner();
    const auto ActorComponents = MeshOwnerActor->GetComponentsByInterface(UWeaponAttackableComponent::StaticClass());
    for(const auto ActorComponent : ActorComponents)
    {
        const auto WeaponAttackable = Cast<IWeaponAttackableComponent>(ActorComponent);
        if(WeaponAttackable == nullptr)	continue;
        WeaponAttackable->WeaponAttacking();
    }

    저의 경우에는 MeshComp를 활용해서 액터를 받아와 처리하는 작업 등을 했습니다.

     

    Notify State Montage 에서 사용하기

    이건 크게 어려운게 없습니다. 노티파이 트랙에서 우클릭을 하면 cpp 에 있는 Notify State를 간단하게 넣을 수 있습니다.

    이런 식으로 범위를 지정해 Notify 를 활용할 수 있습니다!

    반응형

    댓글

Designed by Tistory.