Quick answer: The most common cause is a mismatch between the warp target name set in code and the name configured in the animation's Motion Warping notify window. These names must be identical and are case-sensitive.
Here is how to fix Unreal motion warping not aligning. You have set up the Motion Warping plugin in Unreal Engine, added a warp target for your melee attack or vault animation, and played the montage — but the character plays the animation in place without moving toward the target at all. The animation looks correct but the character does not close the distance, does not rotate to face the target, or overshoots wildly. Motion Warping depends on several systems working in concert, and a misconfiguration in any one of them causes the warp to silently fail.
The Symptom
Your character plays an AnimMontage that should warp the character toward a target location or actor, but no warping occurs. The animation plays with its original baked-in root motion, ignoring the warp target entirely. The character might lunge forward based on the animation's root motion but does not redirect toward the actual target position. There is no error in the Output Log and no visual indication that warping was even attempted.
In some cases, the warp partially works — the character rotates toward the target but does not translate, or moves toward the target but stops short. In other cases, the warp fires but the character ends up at a completely wrong position, offset from the intended target. These partial failures usually indicate the warp target is being found but the notify window timing or root motion extraction is incorrect.
What Causes This
1. Warp target name mismatch between code and animation notify. The Motion Warping system matches targets by name. When you call AddOrUpdateWarpTarget in C++, you provide a name string. The Motion Warping notify window on the AnimMontage also has a WarpTargetName property. These must be exactly identical, including case. If they differ by even one character, the warping system finds no matching target for the notify window and the animation plays unwarped.
2. Root motion is not enabled on the montage or character. Motion Warping works by modifying root motion data extracted from the animation. If the AnimMontage does not have root motion baked in, or if the animation sequence it references has no root bone movement, there is nothing for the warping system to modify. Similarly, if the character's movement component has bUseRootMotion disabled or the AnimInstance is not configured to extract root motion, the warped motion data is computed but never applied to the character.
3. Missing or incorrectly timed Motion Warping notify window. The warp only occurs during the time range defined by the MotionWarping notify state on the montage. If the notify window is missing, no warping happens. If the window starts too late or ends too early relative to the root motion in the animation, the character only warps during that partial window and falls short of the target. The window must cover the portion of the animation where the root motion displacement occurs.
4. The MotionWarpingComponent is not added to the character. The character must have a UMotionWarpingComponent attached. This component receives the warp targets and communicates with the animation system to modify root motion. Without it, calls to AddOrUpdateWarpTarget have nowhere to go and produce no effect.
The Fix
Step 1: Add the MotionWarpingComponent and configure warp targets. Your character class needs the component, and you must set warp targets before playing the montage:
// WarpingCharacter.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "WarpingCharacter.generated.h"
class UMotionWarpingComponent;
class UAnimMontage;
UCLASS()
class AWarpingCharacter : public ACharacter
{
GENERATED_BODY()
public:
AWarpingCharacter();
UFUNCTION(BlueprintCallable, Category = "Combat")
void ExecuteMeleeAttack(AActor* Target);
UFUNCTION(BlueprintCallable, Category = "Movement")
void ExecuteVault(FVector VaultTarget, FVector VaultLanding);
protected:
UPROPERTY(VisibleAnywhere, Category = "Components")
UMotionWarpingComponent* MotionWarpingComp;
UPROPERTY(EditDefaultsOnly, Category = "Combat")
UAnimMontage* MeleeAttackMontage;
UPROPERTY(EditDefaultsOnly, Category = "Movement")
UAnimMontage* VaultMontage;
};
// WarpingCharacter.cpp
#include "WarpingCharacter.h"
#include "MotionWarpingComponent.h"
AWarpingCharacter::AWarpingCharacter()
{
MotionWarpingComp = CreateDefaultSubobject
<UMotionWarpingComponent>(
TEXT("MotionWarping"));
}
void AWarpingCharacter::ExecuteMeleeAttack(AActor* Target)
{
if (!Target || !MeleeAttackMontage || !MotionWarpingComp)
return;
// Clear any previous warp targets
MotionWarpingComp->RemoveWarpTarget("AttackTarget");
// Add warp target - name MUST match the notify window
FMotionWarpingTarget WarpTarget;
WarpTarget.Name = FName("AttackTarget");
WarpTarget.Location = Target->GetActorLocation();
WarpTarget.Rotation = (Target->GetActorLocation()
- GetActorLocation()).Rotation();
MotionWarpingComp->AddOrUpdateWarpTarget(WarpTarget);
UE_LOG(LogTemp, Log,
TEXT("Warp target 'AttackTarget' set at %s"),
*WarpTarget.Location.ToString());
// Play the montage - warping happens automatically
PlayAnimMontage(MeleeAttackMontage);
}
void AWarpingCharacter::ExecuteVault(
FVector VaultTarget, FVector VaultLanding)
{
if (!VaultMontage || !MotionWarpingComp)
return;
// Vault uses two warp targets for start and end
FMotionWarpingTarget StartTarget;
StartTarget.Name = FName("VaultStart");
StartTarget.Location = VaultTarget;
StartTarget.Rotation = (VaultTarget
- GetActorLocation()).Rotation();
FMotionWarpingTarget EndTarget;
EndTarget.Name = FName("VaultEnd");
EndTarget.Location = VaultLanding;
EndTarget.Rotation = (VaultLanding
- VaultTarget).Rotation();
MotionWarpingComp->AddOrUpdateWarpTarget(StartTarget);
MotionWarpingComp->AddOrUpdateWarpTarget(EndTarget);
PlayAnimMontage(VaultMontage);
}
The warp target name "AttackTarget" in code must exactly match the WarpTargetName property set on the Motion Warping notify state in the AnimMontage editor. Open your montage, find the MotionWarping notify window, and verify the name matches. This is the single most common point of failure.
Step 2: Configure the AnimMontage for root motion warping. The montage must have root motion enabled and the notify window must be properly placed. Verify these settings in the montage asset:
// Diagnostic: verify motion warping is configured correctly
void AWarpingCharacter::DebugMotionWarping()
{
if (!MotionWarpingComp)
{
UE_LOG(LogTemp, Error,
TEXT("WARP DEBUG: No MotionWarpingComponent"));
return;
}
// Check if component is active
UE_LOG(LogTemp, Log,
TEXT("WARP DEBUG: Component active: %s"),
MotionWarpingComp->IsActive()
? TEXT("YES") : TEXT("NO"));
// Verify root motion is enabled on the mesh
UAnimInstance* AnimInst =
GetMesh()->GetAnimInstance();
if (AnimInst)
{
UE_LOG(LogTemp, Log,
TEXT("WARP DEBUG: RootMotionMode: %d"),
(int32)AnimInst->RootMotionMode);
}
// Check movement component root motion setting
UCharacterMovementComponent* CMC =
GetCharacterMovement();
if (CMC)
{
UE_LOG(LogTemp, Log,
TEXT("WARP DEBUG: MovementComp allows "
"root motion: %s"),
CMC->bAllowPhysicsRotationDuringAnimRootMotion
? TEXT("YES") : TEXT("NO"));
}
// Verify the montage has root motion
if (MeleeAttackMontage)
{
UE_LOG(LogTemp, Log,
TEXT("WARP DEBUG: Montage '%s' bEnableRM: %s"),
*MeleeAttackMontage->GetName(),
MeleeAttackMontage->bEnableRootMotionTranslation
? TEXT("YES") : TEXT("NO"));
}
}
Step 3: Ensure the MotionWarping plugin is enabled and dependencies are set. The MotionWarping plugin must be enabled in your .uproject file and the module must be listed in your Build.cs. If the plugin is not loaded, the UMotionWarpingComponent class will not exist and your code will fail to compile or the component will be silently null at runtime in packaged builds.
Related Issues
If warping works but the character slides instead of snapping cleanly, the notify window timing does not match the root motion displacement in the animation. Adjust the window start and end frames so they exactly cover the movement phase of the animation. If the character warps to the wrong height, check whether the warp target's Z coordinate is correct and whether the warping mode is set to warp translation on all axes or just XY.
If warping works in PIE but not in packaged builds, verify that the MotionWarping plugin is included in your packaging settings and that the MotionWarping module is listed in your Build.cs PublicDependencyModuleNames. Missing module dependencies compile fine in editor but fail to link in packaged builds.