mcpField
U
ue-animation-system

ue-animation-system

github.com/quodsoler開発4191.2k 回インストール4 週間前に更新
リポジトリ

ue-animation-system について

UE 5.8 のアニメーション開発スキルです。ランタイム API とアニメーションプラグインを扱い、アニメーションインスタンス、モンタージュ、通知、カーブ、ブレンドスペース、ステートマシンなどを解説します。

主な機能

  1. 01AnimInstance とワーカースレッド用プロキシ
  2. 02モンタージュ再生と終了コールバック
  3. 03アニメーション通知と通知ステート
  4. 04カーブ、ブレンドスペース、ステートマシン
  5. 05リンクアニメーションレイヤーとルートモーション

活用シーン

  1. 01スレッドセーフなアニメーション更新の実装
  2. 02モンタージュ再生とブレンドアウト終了処理
  3. 03アニメーション通知によるゲームロジックの起動
  4. 04ロコモーション用ブレンドスペースとステートマシンの設定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/quodsoler/unreal-engine-skills --skill ue-animation-system

インストール後、Claude Code で/ue-animation-systemを入力して読み込まれたか確認します。

同梱ファイルreferences/anim-notify-reference.mdreferences/locomotion-setup.md

詳細

UE Animation System

対象エンジン:UE 5.8。以下の API は 5.8 のヘッダーに照らして検証済みです。以前の形式は「非推奨 — 使用しない」に記載しています。

Engine モジュールのランタイムアニメーション経路を扱います。UAnimInstance、FAnimInstanceProxy、UAnimMontage、UAnimNotify/UAnimNotifyState、カーブ、ブレンドスペース、アニメーションステートマシン、リンクアニメーションレイヤー、ルートモーションに加え、5.8 に同梱されるアニメーションプラグイン(PoseSearch、MotionWarping、Chooser、IKRig、ControlRig、BlendStack、OptimusCore、UAF)を対象とします。Build.cs:Runtime/Engine/Classes/Animation 以下のすべてには Engine、FAnimNode_LayeredBoneBlend などのヘルパーアニメーションノードには AnimGraphRuntime を使用します。プラグインモジュール名は以下の各行に記載しています。

コンテキスト

.agents/ue-project-context.md が存在する場合は読み込んでください(モジュール名、規約、有効なプラグイン、GAS/ネットワーク設定)。存在しなくても作業を中断しないでください。

リクエストとコードベースから対象領域を特定してください。解釈が2通り考えられ、それによって生成するコードが異なる場合に限り、質問してください。

リクエストの内容…参照先
AnimInstance のサブクラス、スレッドセーフな更新、プロキシAnimInstance と Proxy
モンタージュの再生/停止、セクション移動、終了コールバックモンタージュ
ノーティファイ、ノーティファイステート、分岐ポイント、ノーティファイのタイミングアニメーションノーティファイ
カーブ値、モーフターゲット、カーブメタデータアニメーションカーブ
ブレンドスペース、ステートマシン、エイムオフセット、レイヤーブレンドブレンドスペースとステートマシン
リンクアニメーショングラフ、モードごとの移動処理の切り替えリンクアニメーショングラフとレイヤー
ルートモーションの抽出とモードルートモーション
モーションマッチング、ワーピング、IK Rig、Control Rig、デフォーマー5.8 アニメーションプラグイン

AnimInstance と Proxy

UAnimInstance(Animation/AnimInstance.h)は2つのフェーズで実行されます。ゲームスレッド:NativeUpdateAnimation — ゲームプレイの状態を安全に読み取れます。ワーカースレッド:NativeThreadSafeUpdateAnimation とブレンドツリーの評価。ゲームプレイの状態はゲームスレッドでキャッシュし、ワーカースレッドではキャッシュした値のみを読み取ってください。

仮想関数の原文(AnimInstance.h:1436-1457 は public、:1716-1719 は protected):

virtual void NativeInitializeAnimation();
virtual void NativeUpdateAnimation(float DeltaSeconds);
virtual void NativeThreadSafeUpdateAnimation(float DeltaSeconds);
virtual void NativePostEvaluateAnimation();
virtual void NativeUninitializeAnimation();
virtual void NativeBeginPlay();
virtual FAnimInstanceProxy* CreateAnimInstanceProxy();               // protected
virtual void DestroyAnimInstanceProxy(FAnimInstanceProxy* InProxy);  // protected

FAnimInstanceProxy(Public/Animation/AnimInstanceProxy.h)は、ワーカースレッド用のデータコンテナです。オーバーライド可能な箇所は protected です(:603-669)。

virtual void Initialize(UAnimInstance* InAnimInstance);
virtual void PreUpdate(UAnimInstance* InAnimInstance, float DeltaSeconds);
virtual void Update(float DeltaSeconds) {}
virtual bool Evaluate(FPoseContext& Output) { return false; }
virtual void PostUpdate(UAnimInstance* InAnimInstance) const;
virtual void Uninitialize(UAnimInstance* InAnimInstance);

protected テンプレートの GetProxyOnGameThread<T>()(:1746)および GetProxyOnAnyThread<T>()(:1769)を使って、プロキシにアクセスします。

// MyAnimInstance.h
#pragma once

#include "CoreMinimal.h"
#include "Animation/AnimInstance.h"
#include "Animation/AnimInstanceProxy.h"
#include "MyAnimInstance.generated.h"

class ACharacter;
class UCharacterMovementComponent;

USTRUCT()
struct FMyAnimInstanceProxy : public FAnimInstanceProxy
{
    GENERATED_BODY()

    FMyAnimInstanceProxy() = default;
    explicit FMyAnimInstanceProxy(UAnimInstance* InAnimInstance)
        : FAnimInstanceProxy(InAnimInstance) {}

    // Written on the game thread in PreUpdate, read on the worker thread in Update.
    FVector Velocity = FVector::ZeroVector;
    float Speed = 0.f;
    bool bIsFalling = false;

protected:
    virtual void PreUpdate(UAnimInstance* InAnimInstance, float DeltaSeconds) override;
    virtual void Update(float DeltaSeconds) override;
};

UCLASS()
class MYGAME_API UMyAnimInstance : public UAnimInstance
{
    GENERATED_BODY()

public:
    virtual void NativeInitializeAnimation() override;
    virtual void NativeUpdateAnimation(float DeltaSeconds) override;
    virtual void NativeThreadSafeUpdateAnimation(float DeltaSeconds) override;
    virtual void NativeUninitializeAnimation() override;

protected:
    virtual FAnimInstanceProxy* CreateAnimInstanceProxy() override;
    virtual void DestroyAnimInstanceProxy(FAnimInstanceProxy* InProxy) override;

    UPROPERTY(Transient)
    TObjectPtr<ACharacter> OwningCharacter;

    UPROPERTY(Transient)
    TObjectPtr<UCharacterMovementComponent> MovementComp;

    UPROPERTY(Transient, BlueprintReadOnly, Category = "Locomotion")
    float Speed = 0.f;

    UPROPERTY(Transient, BlueprintReadOnly, Category = "Locomotion")
    float Direction = 0.f;

    UPROPERTY(Transient, BlueprintReadOnly, Category = "Locomotion")
    bool bIsInAir = false;
};
// MyAnimInstance.cpp
#include "MyAnimInstance.h"
#include "GameFramework/Character.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Kismet/KismetMathLibrary.h"

void FMyAnimInstanceProxy::PreUpdate(UAnimInstance* InAnimInstance, float DeltaSeconds)
{
    FAnimInstanceProxy::PreUpdate(InAnimInstance, DeltaSeconds);

    // Game thread: safe to touch the owning actor here.
    if (const ACharacter* Character = Cast<ACharacter>(InAnimInstance->TryGetPawnOwner()))
    {
        const UCharacterMovementComponent* Movement = Character->GetCharacterMovement();
        Velocity = Movement->Velocity;
        bIsFalling = Movement->IsFalling();
    }
}

void FMyAnimInstanceProxy::Update(float DeltaSeconds)
{
    FAnimInstanceProxy::Update(DeltaSeconds);
    Speed = Velocity.Size2D(); // Worker thread: proxy members only.
}

FAnimInstanceProxy* UMyAnimInstance::CreateAnimInstanceProxy()
{
    return new FMyAnimInstanceProxy(this);
}

void UMyAnimInstance::DestroyAnimInstanceProxy(FAnimInstanceProxy* InProxy)
{
    delete InProxy;
}

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

    OwningCharacter = Cast<ACharacter>(TryGetPawnOwner());
    if (OwningCharacter)
    {
        MovementComp = OwningCharacter->GetCharacterMovement();
    }
}

void UMyAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
    Super::NativeUpdateAnimation(DeltaSeconds);

    if (!OwningCharacter || !MovementComp)
    {
        return;
    }

    const FVector CurrentVelocity = MovementComp->Velocity;
    Speed = CurrentVelocity.Size2D();
    bIsInAir = MovementComp->IsFalling();

    if (Speed > 3.f)
    {
        Direction = UKismetMathLibrary::NormalizedDeltaRotator(
            CurrentVelocity.ToOrientationRotator(),
            OwningCharacter->GetActorRotation()).Yaw;
    }
}

void UMyAnimInstance::NativeThreadSafeUpdateAnimation(float DeltaSeconds)
{
    Super::NativeThreadSafeUpdateAnimation(DeltaSeconds);

    // Worker thread: read the proxy, never the owning actor. This runs before the
    // proxy's Update(), so read what PreUpdate wrote, not what Update derives.
    const FMyAnimInstanceProxy& Proxy = GetProxyOnAnyThread<FMyAnimInstanceProxy>();
    Speed = Proxy.Velocity.Size2D();
    bIsInAir = Proxy.bIsFalling;
}

void UMyAnimInstance::NativeUninitializeAnimation()
{
    Super::NativeUninitializeAnimation();
    OwningCharacter = nullptr;
    MovementComp = nullptr;
}

保留中の更新状態は NeedsUpdate()(AnimInstance.h:512)で確認してください。メンバー bNeedsUpdate は非推奨です。

モンタージュ

ソース:Animation/AnimInstance.h、Animation/AnimMontage.h。シグネチャの原文(AnimInstance.h:626-796):

float Montage_Play(UAnimMontage* MontageToPlay, float InPlayRate = 1.f,
    EMontagePlayReturnType ReturnValueType = EMontagePlayReturnType::MontageLength,
    float InTimeToStartMontageAt = 0.f, bool bStopAllMontages = true);
// Same trailing params; override the asset's blend-in (FMontageBlendSettings adds BlendProfile and
// BlendMode, e.g. EMontageBlendMode::Inertialization)
float Montage_PlayWithBlendIn(UAnimMontage* MontageToPlay, const FAlphaBlendArgs& BlendIn, ...);
float Montage_PlayWithBlendSettings(UAnimMontage* MontageToPlay, const FMontageBlendSettings& BlendInSettings, ...);
void  Montage_Stop(float InBlendOutTime, const UAnimMontage* Montage = NULL);
void  Montage_Pause(const UAnimMontage* Montage = NULL);
void  Montage_Resume(const UAnimMontage* Montage);
void  Montage_JumpToSection(FName SectionName, const UAnimMontage* Montage = NULL);
void  Montage_SetNextSection(FName SectionNameToChange, FName NextSection,
          const UAnimMontage* Montage = NULL);
void  Montage_SetPlayRate(const UAnimMontage* Montage, float NewPlayRate = 1.f);
bool  Montage_IsPlaying(const UAnimMontage* Montage) const;
bool  Montage_IsActive(const UAnimMontage* Montage) const;
bool  Montage_GetIsStopped(const UAnimMontage* Montage) const;
float Montage_GetPosition(const UAnimMontage* Montage) const;
void  Montage_SetPosition(const UAnimMontage* Montage, float NewPosition);
float Montage_GetBlendTime(const UAnimMontage* Montage) const;
float Montage_GetPlayRate(const UAnimMontage* Montage) const;
FName Montage_GetCurrentSection(const UAnimMontage* Montage = NULL) const;
void  Montage_SetEndDelegate(FOnMontageEnded& InOnMontageEnded, UAnimMontage* Montage = NULL);
void  Montage_SetBlendingOutDelegate(FOnMontageBlendingOutStarted& InOnMontageBlendingOut,
          UAnimMontage* Montage = NULL);

EMontagePlayReturnType(AnimInstance.h:70)はMontageLengthまたはDurationです。ブレンドアウトが始まると、ポーズのブレンドが続いている間も、Montage_IsPlayingとMontage_IsActiveはfalseを返し、Montage_GetIsStoppedはtrueを返します(Stop()はインスタンスをActiveMontagesMapから削除します。AnimInstance.cpp:3709)。ブレンドアウトの開始にはOnMontageBlendingOut/Montage_SetBlendingOutDelegateを、終了にはOnMontageEndedを使用してください。デリゲート型(AnimInstance.h:79-80)はシングルキャストです:

DECLARE_DELEGATE_TwoParams(FOnMontageEnded, UAnimMontage*, bool /*bInterrupted*/)
DECLARE_DELEGATE_TwoParams(FOnMontageBlendingOutStarted, UAnimMontage*, bool /*bInterrupted*/)

ブロードキャストには、ダイナミックマルチキャストメンバーのOnMontageStarted、OnMontageEnded、OnMontageBlendingOutを使用してください(:758-770)。

void UMyWeaponComponent::PlayAttackMontage(USkeletalMeshComponent* Mesh, UAnimMontage* Montage)
{
    UAnimInstance* AnimInst = Mesh ? Mesh->GetAnimInstance() : nullptr;
    if (!AnimInst || !Montage)
    {
        return;
    }

    // Play FIRST: the delegate setters resolve the active montage instance,
    // which does not exist until Montage_Play has created it.
    if (AnimInst->Montage_Play(Montage) <= 0.f)
    {
        return;
    }

    FOnMontageEnded EndDelegate;
    EndDelegate.BindUObject(this, &UMyWeaponComponent::OnAttackEnded);
    AnimInst->Montage_SetEndDelegate(EndDelegate, Montage);

    FOnMontageBlendingOutStarted BlendOutDelegate;
    BlendOutDelegate.BindUObject(this, &UMyWeaponComponent::OnAttackBlendingOut);
    AnimInst->Montage_SetBlendingOutDelegate(BlendOutDelegate, Montage);
}

void UMyWeaponComponent::OnAttackEnded(UAnimMontage* Montage, bool bInterrupted) {}
void UMyWeaponComponent::OnAttackBlendingOut(UAnimMontage* Montage, bool bInterrupted) {}

USkeletalMeshComponent(Components/SkeletalMeshComponent.h):

UAnimInstance* GetAnimInstance() const;                                  // :1111
void PlayAnimation(class UAnimationAsset* NewAnimToPlay, bool bLooping); // :1258
virtual void SetAnimInstanceClass(class UClass* NewClass);               // :1096
void LinkAnimClassLayers(TSubclassOf<UAnimInstance> InClass);            // :1194
void UnlinkAnimClassLayers(TSubclassOf<UAnimInstance> InClass);          // :1205
UAnimInstance* GetLinkedAnimGraphInstanceByTag(FName InTag) const;       // :1160
void SetAnimationMode(EAnimationMode::Type InAnimationMode,
    bool bForceInitAnimScriptInstance = true);                           // :1246

PlayAnimationを実行すると、コンポーネントはシングルノードモードになります。SetAnimInstanceClassを実行すると、アニメーションブループリントモードになります。同じコンポーネントで両方を併用すると、一方が通知なく破棄されます。

マルチプレイヤー:GASを使用する場合は、UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(GameplayAbilities/Public/Abilities/Tasks/AbilityTask_PlayMontageAndWait.h:66)を通じてモンタージュを制御してください。詳しくはue-gameplay-abilitiesを参照してください。GASを使用しない場合は、モンタージュの選択を独自にレプリケートし、レプリケーションコールバックからMontage_Playを呼び出してください。ネットワークロールごとに個別に呼び出すことは避けてください。

アニメーション通知

ソース:Animation/AnimNotifies/AnimNotify.h、AnimNotifyState.h。以下の正確なシグネチャをオーバーライドしてください:

// UAnimNotify (AnimNotify.h:85-86, :59)
virtual void Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
    const FAnimNotifyEventReference& EventReference);
virtual void BranchingPointNotify(FBranchingPointNotifyPayload& BranchingPointPayload);
FString GetNotifyName() const;  // BlueprintNativeEvent: override GetNotifyName_Implementation

// UAnimNotifyState (AnimNotifyState.h:74-80)
virtual void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
    float TotalDuration, const FAnimNotifyEventReference& EventReference);
virtual void NotifyTick(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
    float FrameDeltaTime, const FAnimNotifyEventReference& EventReference);
virtual void NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
    const FAnimNotifyEventReference& EventReference);

Received_Notify(AnimNotify.h:62)およびReceived_NotifyBegin/Received_NotifyTick/Received_NotifyEnd(AnimNotifyState.h:45-51)はBlueprintImplementableEventのエントリーポイントです。これらはブループリントで実装し、C++ではオーバーライドしないでください。

モンタージュ通知のタイミングはイベントごとに異なります。FAnimNotifyEvent::MontageTickType(Public/Animation/AnimTypes.h:318)は、EMontageNotifyTickType::Queued(評価フェーズの最後に発火します。ヘッダーには、セクションやモンタージュの位置の変更には適さないと記載されています)またはBranchingPoint(遭遇した時点で発火し、セクションの変更に適しています)です。ネイティブ通知は、コンストラクターでbIsNativeBranchingPoint = trueを設定することにより、分岐点の処理経路を強制します(AnimNotify.h:123、AnimNotifyState.h:108)。

OnPlayMontageNotifyBegin/OnPlayMontageNotifyEndを使用すると、AnimInstanceの外部から名前付きモンタージュ通知をバインドできます(AnimInstance.h:1820-1823、型はFPlayMontageAnimNotifyDelegate)。

組み込み通知の一覧、カスタム通知と通知ステートの完全な例、FAnimNotifyEventのフィールド、リンクされたインスタンスへの伝播については、references/anim-notify-reference.mdを参照してください。

アニメーションカーブ

5.8ではカーブをFNameで参照します。スマートネーム、カーブUID、マッピングルックアップはありません。

// UAnimInstance (AnimInstance.h:1241-1273)
float GetCurveValue(FName CurveName) const;
bool  GetCurveValue(FName CurveName, float& OutValue) const;
bool  GetCurveValueWithDefault(FName CurveName, float DefaultValue, float& OutValue) const;
void  SetMorphTarget(FName MorphTargetName, float Value);

// USkeletalMeshComponent (SkeletalMeshComponent.h:664-667)
bool GetCurveValue(FName CurveName, float DefaultValue, float& Value) const;
const FBlendedHeapCurve& GetAnimCurves() const;

カーブごとのフラグ(カーブがマテリアルまたはモーフターゲットを制御するかどうか)は、スケルトンのCurveMetaDataにあります(Animation/Skeleton.h:387-467):GetCurveMetaData(FName)、AddCurveMetaData(FName CurveName, bool bTransact = true)、GetCurveMetaDataNames(TArray<FName>& OutNames)、SetCurveMetaDataMorphTarget(FName CurveName, bool bOverrideMorphTarget)。

ブレンドスペースとステートマシン

ブレンドスペースはAnimGraphノードがサンプリングするアセットです。AnimGraphが読み取るUPROPERTYメンバーから値を指定します。

アセットクラスヘッダー用途
UBlendSpaceAnimation/BlendSpace.h:4702軸ブレンド。通常はDirection x Speedです
UBlendSpace1DAnimation/BlendSpace1D.h:191軸。通常はSpeedです
UAimOffsetBlendSpaceAnimation/AimOffsetBlendSpace.h:20ベースポーズに加算するエイムポーズ

軸のスムージングにはFInterpolationParameter(BlendSpace.h:80-110)を使用します。InterpolationTime、DampingRatio、MaxSpeed、およびTEnumAsByte<EFilterInterpolationType>型のInterpolationTypeがあり、値はBSIT_Average、BSIT_Linear、BSIT_Cubic、BSIT_EaseInOut、BSIT_ExponentialDecay、BSIT_SpringDamperです(Engine/EngineTypes.h:1356)。

NativeInitializeAnimation(AnimInstance.h:1461-1473)から、ネイティブC++をコンパイル済みステートマシンにバインドします。

// CanStartMoving() and OnLandEntered() are members of UMyAnimInstance.
// DECLARE_DELEGATE_RetVal(bool, FCanTakeTransition)                     AnimInstance.h:118
// DECLARE_DELEGATE_ThreeParams(FOnGraphStateChanged,
//     const struct FAnimNode_StateMachine&, int32, int32)              AnimInstance.h:121
AddNativeTransitionBinding(FName("LocomotionSM"), FName("Idle"), FName("Walk"),
    FCanTakeTransition::CreateUObject(this, &UMyAnimInstance::CanStartMoving),
    FName("IdleToMoving"));

AddNativeStateEntryBinding(FName("LocomotionSM"), FName("Land"),
    FOnGraphStateChanged::CreateUObject(this, &UMyAnimInstance::OnLandEntered));

実行時には、GetStateMachineIndex(FName MachineName)(:1202)、GetStateMachineInstanceFromName(FName MachineName)(:1191)、およびGetInstanceStateWeight(int32 MachineIndex, int32 StateIndex)(:1116)で照会します。

ブレンドスペース、ステートマシン、ボーンごとのレイヤーブレンド、エイムオフセットの設定全体については、references/locomotion-setup.mdを参照してください。

リンクされたAnim Graphとレイヤー

ソース:Animation/AnimNode_LinkedAnimGraph.h、Animation/AnimNode_LinkedAnimLayer.h。

// UAnimInstance (AnimInstance.h:850-910)
virtual void LinkAnimClassLayers(TSubclassOf<UAnimInstance> InClass);
virtual void UnlinkAnimClassLayers(TSubclassOf<UAnimInstance> InClass);
UAnimInstance* GetLinkedAnimLayerInstanceByClass(TSubclassOf<UAnimInstance> InClass,
    bool bCheckForChildClass = false) const;
void LinkAnimGraphByTag(FName InTag, TSubclassOf<UAnimInstance> InClass);
UAnimInstance* GetLinkedAnimGraphInstanceByTag(FName InTag) const;

LinkAnimClassLayers(nullptr)を呼び出すと、デフォルトのレイヤー実装に戻ります。リンクされたインスタンス間のNotifyフローは、SetReceiveNotifiesFromLinkedInstances(bool bSet)およびSetPropagateNotifiesToLinkedInstances(bool bSet)(:523-531)で設定するか、ノードごとにbReceiveNotifiesFromLinkedInstances/bPropagateNotifiesToLinkedInstances(AnimNode_LinkedAnimGraph.h:76-80)で設定します。SetUseMainInstanceMontageEvaluationData(bool bSet)(:537)を設定すると、リンクされたレイヤーでメインインスタンスのモンタージュ評価データを共有します。

リンクされたノードのPendingBlendInDuration/PendingBlendOutDurationで切り替えをブレンドするか(AnimNode_LinkedAnimGraph.h:60-67)、コードからブレンドをリクエストします。

// AnimInstance.h:1006
AnimInst->RequestSlotGroupInertialization(FName("DefaultGroup"), 0.2f);

ルートモーション

ERootMotionMode::Type(Animation/AnimEnums.h:27-42):NoRootMotionExtraction、IgnoreRootMotion、RootMotionFromEverything、RootMotionFromMontagesOnly。ヘッダーでは、RootMotionFromEverythingはネットワークマルチプレイヤーには不適切であり、RootMotionFromMontagesOnlyがネットワーク向けの選択肢であると記載されています。

// AnimInstance.h:372, :1066, :1662
TEnumAsByte<ERootMotionMode::Type> RootMotionMode;   // UPROPERTY(EditDefaultsOnly)
void SetRootMotionMode(TEnumAsByte<ERootMotionMode::Type> Value);
FRootMotionMovementParams ConsumeExtractedRootMotion(float Alpha);

// Suppress root motion for part of a montage (AnimMontage.h:562-564)
if (FAnimMontageInstance* Inst = AnimInst->GetActiveInstanceForMontage(Montage))
{
    Inst->PushDisableRootMotion();
    // ... later ...
    Inst->PopDisableRootMotion();
}

モンタージュのルートモーションとRootMotionSourceは別のシステムです。モンタージュの経路ではポーズ由来のデルタをムーブメントコンポーネントに渡し、RootMotionSourceではアニメーションを伴わずにスクリプトによる移動を適用します。ネットワーク予測、補正、およびbAllowPhysicsRotationDuringAnimRootMotion(GameFramework/CharacterMovementComponent.h:1083)については、ue-character-movementを参照してください。

5.8 アニメーションプラグイン

特に記載がない限り、各プラグインは .uproject でデフォルトで無効になっています。使用する型がある場合は、Build.cs にモジュールを追加してください。

プラグイン/モジュール5.8 での成熟度主な型とヘッダー
PoseSearch製品版FAnimNode_MotionMatching (PoseSearch/AnimNode_MotionMatching.h:18)、UPoseSearchDatabase (PoseSearch/PoseSearchDatabase.h:502)。軌道は FTransformTrajectorySample (Runtime/Engine/Public/Animation/TrajectoryTypes.h:18) です
Chooser製品版UChooserTable (Chooser.h:22)、UChooserFunctionLibrary (ChooserFunctionLibrary.h:18) — データ駆動型のアセット選択機能で、モーションマッチングに渡す用途が一般的です
MotionWarping5.8 ではベータUMotionWarpingComponent (MotionWarpingComponent.h:100)、URootMotionModifier (RootMotionModifier.h:71)。回転オフセットには AdditionalRotationOffset (RootMotionModifier.h:407) を使用します
IKRig製品版、デフォルトで有効UIKRigDefinition (Rig/IKRigDefinition.h:206)、UIKRetargeter (Retargeter/IKRetargeter.h:70) — ランタイムの IK ソルビングとアニメーションのリターゲティングに使用します
ControlRig製品版、デフォルトで有効UControlRig (ControlRig.h:63)、FAnimNode_ControlRig (AnimNode_ControlRig.h:21) — AnimGraph 内で評価されるプロシージャルリグです
BlendStack製品版FAnimNode_BlendStack と FAnimNode_BlendStack_Standalone (BlendStack/AnimNode_BlendStack.h:272,150) — モーションマッチングが基盤とするブレンドスタックです
OptimusCore (Deformer Graph)5.8 ではベータUOptimusDeformer (OptimusDeformer.h:132) — GPU メッシュ変形グラフです
UAF5.8 では実験的Plugins/Experimental/UAF/UAF、モジュール UAF:UUAFRigVMAsset (AnimNextRigVMAsset.h:61)、UUAFComponent (Component/AnimNextComponent.h:77) — 後継のアニメーションフレームワークです

非推奨 — 使用しないでください

出力しないもの5.8 で使用するものソース
FSmartName、FSmartNameMapping、FSmartNameContainer通常の FName カーブ名Animation/SmartName.h:20,80,121 の UE_DEPRECATED(5.8)
Skeleton のスマートネームカーブテーブルUSkeleton の CurveMetaData アクセサーAnimation/Skeleton.h:505 の UE_DEPRECATED(5.7)
AnimCurveUIDFName カーブ名Animation/Skeleton.h:384 の UE_DEPRECATED(5.7)
UAnimInstance::bNeedsUpdateNeedsUpdate()Animation/AnimInstance.h:389 の UE_DEPRECATED(5.7)
USkeletalMeshComponent::SetAnimClassSetAnimInstanceClassComponents/SkeletalMeshComponent.h:1084 の UE_DEPRECATED(5.5)
USkeletalMeshComponent::AnimCurves メンバーGetAnimCurves() / GetCurveValue()Components/SkeletalMeshComponent.h:470 の UE_DEPRECATED(5.6)
UAnimSequence::RetargetSourceAsset メンバーGetRetargetSourceAsset / SetRetargetSourceAssetAnimation/AnimSequence.h:305 の UE_DEPRECATED(5.5)
FTrajectorySampleFTransformTrajectorySamplePublic/Animation/MotionTrajectoryTypes.h:10 の UE_DEPRECATED(5.6)
FPoseSearchQueryTrajectorySampleFTransformTrajectorySamplePoseSearch/PoseSearchTrajectoryTypes.h:16 の UE_DEPRECATED(5.6)
FPoseSearchDatabaseSequence、FPoseSearchDatabaseBlendSpaceFPoseSearchDatabaseAnimationAssetPoseSearch/PoseSearchDatabase.h:228 の UE_DEPRECATED(5.7)
EMotionWarpRotationType::OppositeDefault / OppositeFacingAdditionalRotationOffsetMotionWarping/RootMotionModifier.h:309,312 の UE_DEPRECATED(5.8)
FAnimInstanceProxy::GetSlotInertializationRequestGetSlotInertializationRequestDataPublic/Animation/AnimInstanceProxy.h:444 の UE_DEPRECATED(5.5)
SetSubInstanceClassByTag、GetSubInstanceByTagLinkAnimGraphByTag、GetLinkedAnimGraphInstanceByTagAnimation/AnimInstance.h:860,845 の UE_DEPRECATED(4.24)
SetLayerOverlay、ClearLayerOverlayLinkAnimClassLayers、UnlinkAnimClassLayersAnimation/AnimInstance.h:868,880 の UE_DEPRECATED(4.24)
GetLayerSubInstanceByClassGetLinkedAnimLayerInstanceByClassAnimation/AnimInstance.h:906 の UE_DEPRECATED(4.24)

よくある間違い

**NativeThreadSafeUpdateAnimation で所有アクターにアクセスする:**この関数はワーカースレッドで実行されるため、TryGetPawnOwner()、コンポーネントへの問い合わせ、トレースは安全ではありません。必要な値は NativeUpdateAnimation または FAnimInstanceProxy::PreUpdate でキャッシュし、ワーカースレッドではそれらのメンバーだけを読み取ってください。

Montage_Play より前にモンタージュデリゲートをバインドする:Montage_SetEndDelegate と Montage_SetBlendingOutDelegate はアクティブなモンタージュインスタンスを参照しますが、その時点ではまだ存在しません。先に Montage_Play を呼び出し、戻り値がゼロより大きいことを確認してからバインドしてください。

**C++ で Received_Notify をオーバーライドする:**これは BlueprintImplementableEvent です。代わりに Notify(USkeletalMeshComponent*, UAnimSequenceBase*, const FAnimNotifyEventReference&) をオーバーライドしてください。

**キューに入れられた通知からセクションへジャンプする:**キューに入れられた通知は評価フェーズの後に発火するため、そこから Montage_JumpToSection を呼び出すと、1 フレーム遅れて反映されます。bIsNativeBranchingPoint = true を設定し、セクション制御には BranchingPointNotify をオーバーライドしてください。

スマートネームまたは UID でカーブを検索する:FSmartName、FSmartNameMapping、AnimCurveUID は非推奨です。GetCurveValue には FName を渡し、カーブごとのフラグは CurveMetaData に保持してください。

プロキシのオーバーライドを public として宣言する:FAnimInstanceProxy の Initialize、PreUpdate、Update、Evaluate、PostUpdate は protected です。また、UAnimInstance の CreateAnimInstanceProxy / DestroyAnimInstanceProxy も protected です。アクセスレベルを維持しないと、オーバーライドをコンパイルできません。

**基底クラスの呼び出しを省略する:**すべての Native* オーバーライドでは Super:: 形式の関数を呼び出し、すべてのプロキシオーバーライドでは FAnimInstanceProxy::<Name> を呼び出してください。基底クラスの実装は、モンタージュのティック処理、通知キュー、プロキシの管理を担います。

関連スキル

  • ue-character-movement — UCharacterMovementComponent、RootMotionSource、ネットワークでのルートモーションの予測と補正。
  • ue-gameplay-abilities — UAbilityTask_PlayMontageAndWait、GAS のモンタージュレプリケーション、アビリティ駆動のアニメーション。
  • ue-actor-component-architecture — USkeletalMeshComponent のセットアップ、アタッチメント、コンポーネントのティック順序。
  • ue-sequencer-cinematics — レベルシーケンスのアニメーショントラックと、スケルタルメッシュでのシネマティック再生。
  • ue-mass-entity — アクターごとの AnimInstance ではなく、Mass の表現を通じた大規模な群衆アニメーション。
  • ue-cpp-foundations — デリゲートのバインド、UPROPERTY/UFUNCTION 指定子、TObjectPtr。
  • ue-niagara-effects — Notify とスケルタルメッシュのデータインターフェースから生成される Niagara システム。
  • ue-audio-system — UAudioComponent、MetaSounds、サブミックス、減衰、同時実行数
  • ue-mover — Mover プラグイン:移動モード、レイヤー化されたムーブ、ロールバックネットワーク

コメント