LoginSignup
0
1

More than 3 years have passed since last update.

UE4 AnimationModifierについてのメモ

Posted at

概要

UnrealEngine のアニメーションモディファイア(AnimationModifier)についてのメモです。

環境

Windows10
Visual Studio 2017
UnrealEngine 4.24

参考

以下を参考にさせて頂きました、ありがとうございます。

[UE4] UE 4.16 の新機能!Animation Modifier について
UE4 アニメーションモディファイア(Animation Modifier)で自動的にアニメーション情報を追加する

AnimationModifierとは

独立したアセットとして、紐づけたアニメ―ションシーケンスアセットに対してCurve情報やNotify情報を追加できる機能です。(アニメ―ションモンタージュには不可です。)
スケルトンに対して紐づけるとそのスケルトンに紐づいたアニメ―ションシーケンス全てに対して情報が付与されます。
4.16で先行追加された機能のようですが、4.24、4.25でもまだ実験的機能扱いになっています。

Warning.jpg

前準備 - テスト通知を追加

テスト用のアニメ―ション通知を作成します、イベントタグを通知するものとして以下の様に定義しています。通知クラスはC++である必要はありません。

AnimNotity_TestEvent.h
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "Animation/AnimNotifies/AnimNotify.h"
#include "GameplayTagContainer.h"
#include "AnimNotify_TestEvent.generated.h"

class UAnimSequenceBase;
class USkeletalMeshComponent;
struct FGameplayTag;

UCLASS(const, hidecategories=Object, collapsecategories, meta=(DisplayName="TestEvent"))
class TEST_API UAnimNotify_TestEvent : public UAnimNotify
{
    GENERATED_BODY()

public:

    UAnimNotify_TestEvent();

    // Begin UAnimNotify interface
    virtual FString GetNotifyName_Implementation() const override;
    virtual void Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation) override;
#if WITH_EDITOR
    virtual void ValidateAssociatedAssets() override;
#endif
    // End UAnimNotify interface

    // イベントタグ
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AnimNotify_TestEvent")
    FGameplayTag    EventTag;

};

AnimNotity_TestEvent.cpp
#include "./AnimNotify_TestEvent.h"
#include "Components/SkeletalMeshComponent.h"
#include "Kismet/GameplayStatics.h"
#include "Animation/AnimSequenceBase.h"
#include "Abilities/GameplayAbilityTypes.h"
#include "AbilitySystemBlueprintLibrary.h"

#if WITH_EDITOR
#include "Logging/MessageLog.h"
#include "Misc/UObjectToken.h"
#endif

UAnimNotify_TestEvent::UAnimNotify_TestEvent()
    : Super()
{
}

void UAnimNotify_TestEvent::Notify(
    class USkeletalMeshComponent*   MeshComp,       // スケルタルメッシュコンポーネント
    class UAnimSequenceBase*        Animation       // アニメ―ション
    )
{
    AActor* _Actor = MeshComp->GetOwner();
    if (_Actor) {

        if (!EventTag.IsValid()){
            EventTag = FGameplayTag::RequestGameplayTag(FName("Event.Test"));
        }

        // イベント発行
        FGameplayEventData _Payload;
        _Payload.Target = _Actor;
        UAbilitySystemBlueprintLibrary::SendGameplayEventToActor(_Actor, EventTag, _Payload);
    }

}

// 通知名
FString UAnimNotify_TestEvent::GetNotifyName_Implementation() const
{
    return( FString(TEXT("TestEvent")) );
}

#if WITH_EDITOR
void UAnimNotify_TestEvent::ValidateAssociatedAssets()
{
    static const FName NAME_AssetCheck("AssetCheck");

}
#endif

ゲームプレイタグを使用しています、当然タグがないとコールバックエラーがでます。

AnimationModifierの使用(BP)

ブループリントで作成するケースです。

BPを作成

AnimationModifierを継承してBPを作成します。

MakeBP.jpg

作成したBPに対し、適用イベントOnApplyと元に戻すイベントOnRevertを以下の様に書きます。
テストコードではアニメ―ショントラック追加と通知追加をしてみます。

AnimModifierBP.jpg

OnApplyでは Add Animation Notify Trackでアニメ―ショントラック[EventTr]を追加してそのトラックに対し、Add Animation Notify Eventで通知[TestEvent] を追加しています。
OnRevertではRemove Animation Notify Events by Nameにて[TestEvent]を削除して、Remove Animation Notify Trackでアニメ―ショントラック[EventTr]を消しています。(この場合、アニメ―ショントラックだけ消せば通知も消えます)

また、OnRevertOnApplyで追加した内容を全部消す形で実装しないと、複数回適用した場合、データが意図しない形になるので注意が必要です。

アニメ―ションシーケンスに適用する

アニメ―ションシーケンスの[アニメ―ションデータモディファイアブループリント管理のタブ]から先ほど作成したBPを選択し追加します。

ModifierSetting.jpg

[すべてのモディファイアを適用]ボタンを押下するとBPのOnApplyでの内容で適用されます。

右クリックで「モディファイアを適用」「モディファイアを取り消す」「モディファイアを削除」が選択できます。どれを選んでも OnRevertイベントが一回発生するようです。

ModifierSettingMenu.jpg

適用結果

適用する前のアニメ―ションシーケンスがこの状態です。
AS_Notify1.jpg

「モディファイアを適用」をした後がこの状態になります。

AS_Notify2.jpg

[EventTr]トラックが追加され、そこに通知[TestEvent]が追加されています。

「モディファイアを取り消す」を選択すると最初の状態に戻りますが、OnRevert処理で、OnApplyで追加した内容を全部消さないと以下のようなおかしな状態になってしまいますので注意が必要です。

AS_Notify3.jpg

AnimationModifierの使用(C++)

C++で作成するケースです。エディタ用モジュールで作成しないとパッケージ時にエラーがでてしまいますので注意が必要です。

uprojectの設定

.uprojectAdditionalDependenciesAnimationModifiers を追加する必要があります。

.uproject
"Modules": [
    {
        "Name": "MyGame",
        "Type": "Runtime",
        "LoadingPhase": "Default",
        "AdditionalDependencies": [
            "Engine",
            "UMG",
            "CoreUObject"
        ]
    },
    {
        "Name": "MyGameEd",
        "Type": "Editor",
        "LoadingPhase": "PostEngineInit",
        "AdditionalDependencies": [
            "AnimationModifiers"
        ]
    }
    ],

C++クラスを作成

関連ソース
"Engine\Source\Editor\AnimationModifiers\Public\AnimationModifier.h"

AnimationModifierクラスを継承してC++クラスを追加します。

CreateClass.jpg

追加したクラスに対し、OnApply_ImplementationOnRevert_Implementationをオーバーライドします。
以下BPと処理的には全く同じになるサンプルコードです。

MyAnimationModifier.h
#include "CoreMinimal.h"
#include "AnimationModifier.h"
#include "MyAnimationModifier.generated.h"

UCLASS()
class TESTEDITOR_API UMyAnimationModifier : public UAnimationModifier
{
    GENERATED_BODY()

public:
    // 通知
    virtual void OnApply_Implementation(UAnimSequence* AnimationSequence) override;

    // 戻す
    virtual void OnRevert_Implementation(UAnimSequence* AnimationSequence) override;

};

MyAnimationModifier.cpp
#include "MyAnimationModifier.h"
#include "Animation/AnimSequence.h"
#include "AnimationModifiers/Public/AnimationBlueprintLibrary.h"
#include "{通知クラスのパス}/AnimNotify_TestEvent.h"


void UMyAnimationModifier::OnApply_Implementation(UAnimSequence* AnimationSequence)
{
    // アニメ―ショントラックの追加
    UAnimationBlueprintLibrary::AddAnimationNotifyTrack(AnimationSequence, TEXT("EventTr"), FLinearColor(0.8f, 0.2f, 0.2f));
    // 通知の追加
    UAnimationBlueprintLibrary::AddAnimationNotifyEvent(AnimationSequence, TEXT("EventTr"), 0.1f, UAnimNotify_TestEvent::StaticClass());
}

// 
void UMyAnimationModifier::OnRevert_Implementation(UAnimSequence* AnimationSequence)
{
    // 通知の削除
    UAnimationBlueprintLibrary::RemoveAnimationNotifyEventsByName(AnimationSequence, TEXT("TestEvent"));
    // アニメ―ショントラックの削除
    UAnimationBlueprintLibrary::RemoveAnimationNotifyTrack(AnimationSequence, TEXT("EventTr"));
}

アニメ―ションシーケンスに適用する

BPの時と同様に追加にアニメ―ションシーケンスから「モディファイアを追加」で選択ができるようになります。

AddModifierCPP.jpg

適用結果

結果はBPと同様になります。

補足

BPで使えるノードは Animation Blueprint Library にあります。
BPNode.jpg

C++コードは以下にあります。
"Engine\Source\Editor\AnimationModifiers\Public\AnimationBlueprintLibrary.h"

まとめ

上手く使うと手動で行っていた作業が一部楽になる可能性があるかと思います。特にアクターの違いでアニメ―ションシーケンスアセットは別になっているけれども同じタイミングでの通知を入れないとならないようなケースなどが考えられます。
未だ実験的機能扱いなのが気になるところですが。。:confused:

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1