I’m messing around with pawn movement, so I followed the wiki and added a UPawnMovementComponent to a custom Pawn class. It moves around the level nicely, but every time I attempt to get it’s direction or velocity the result is always zero.
E.g.:
Calling the pawn’s GetVelocity() and taking the length of the vector returns zero.
Even if I set a variable on the class in c++ and grab it via blueprints, it’s zero.
So the pawns movement code looks like:
void AMyPawn::MoveForward(float AxisValue)
{
FVector CameraVector = m_Camera->GetForwardVector();
CameraVector.Z = 0.0f;
CameraVector.Normalize();
m_Direction = CameraVector;
if (GetMovementComponent() && (GetMovementComponent()->UpdatedComponent == RootComponent))
{
GetMovementComponent()->AddInputVector(CameraVector * AxisValue);
}
}
This works great, it moves around nicely, but GetVelocity always returns zero and I cannot figure out why. It’s moving the RootComponent (which is a capsule), is it because the pawn isn’t moving, but the capsule is?
Here is the constructor of the Pawn:
AMyPawn::AMyPawn()
{
PrimaryActorTick.bCanEverTick = true;
m_CapsuleComponent = CreateDefaultSubobject<UCapsuleComponent>(TEXT("RootComponent"));
RootComponent = m_CapsuleComponent;
m_CapsuleComponent->SetCapsuleHalfHeight(100.0f);
m_CapsuleComponent->SetCapsuleRadius(40.0f);
m_CapsuleComponent->SetCollisionProfileName(TEXT("Pawn"));
m_CameraSpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraSpringArm"));
m_CameraSpringArm->SetupAttachment(RootComponent);
m_CameraSpringArm->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, 50.0f), FRotator(-60.0f, 0.0f, 0.0f));
m_CameraSpringArm->TargetArmLength = 300.0f;
m_CameraSpringArm->bEnableCameraLag = true;
m_CameraSpringArm->CameraLagSpeed = 3.0f;
m_Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("GameCamera"));
m_Camera->SetupAttachment(m_CameraSpringArm, USpringArmComponent::SocketName);
//Setup our mesh
m_Mesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Mesh"));
m_Mesh->SetupAttachment(RootComponent);
static ConstructorHelpers::FObjectFinder<USkeletalMesh> MeshAsset(TEXT("/Game/Characters/Test.test"));
if (MeshAsset.Succeeded())
{
m_Mesh->SetSkeletalMesh(MeshAsset.Object);
m_Mesh->SetRelativeLocation(FVector(0.0f, 0.0f, -40.0f));
}
m_MovementComponent = CreateDefaultSubobject<UPlayerPawnMovementComponent>(TEXT("PlayerMovementComponent"));
m_MovementComponent->UpdatedComponent = RootComponent;
AutoPossessPlayer = EAutoReceiveInput::Player0;
}
Here is the movement class, for reference:
void UPlayerPawnMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
// Make sure we can move
if (!PawnOwner || !UpdatedComponent || ShouldSkipUpdate(DeltaTime))
return;
FVector DesiredMovementThisFrame = ConsumeInputVector().GetClampedToMaxSize(1.0f) * DeltaTime * RunSpeed;
if (!DesiredMovementThisFrame.IsNearlyZero())
{
FHitResult Hit;
SafeMoveUpdatedComponent(DesiredMovementThisFrame, UpdatedComponent->GetComponentRotation(), true, Hit);
if (Hit.IsValidBlockingHit())
{
SlideAlongSurface(DesiredMovementThisFrame, 1.f - Hit.Time, Hit.Normal, Hit);
}
}
}
Just to clarify, the issue is, when you want to find out the speed of the pawn, for animations or the like, it never returns a correct speed, so in blueprints when you do Pawn → GetVelocity() → Get Vector Length() it’s zero. So I think I messed up somewhere but where I don’t know.