x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Custom Pawn Velocity Always Zero

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.

Product Version: UE 4.15
Tags:
more ▼

asked May 08 '17 at 02:15 AM in C++ Programming

avatar image

brianempson
8 1 2 1

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

This is because the movement components are required to set the velocity by themselves. If you take a look into FloatingPawnMovement::TickComponent, it first applies the input vector to the velocity, calculates the delta out of the velocity, moves the pawn, and then re-adjusts the velocity in case of collision. And don't forget to call UpdateComponentVelocity() whenever you have changed the velocity!

more ▼

answered May 08 '17 at 07:09 AM

avatar image

Benergy
841 21 4 29

avatar image brianempson May 08 '17 at 04:20 PM

This was it, I didn't do my homework on velocity calculations and should have used a different base class, probably Character.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

This is how APawn returns the velocity

 FVector APawn::GetVelocity() const
 {
     if(GetRootComponent() && GetRootComponent()->IsSimulatingPhysics())
     {
         return GetRootComponent()->GetComponentVelocity();
     }
 
     const UPawnMovementComponent* MovementComponent = GetMovementComponent();
     return MovementComponent ? MovementComponent->Velocity : FVector::ZeroVector;
 }

It checks if the root component is simulating physics, if it is, it returns the component velocity. If it doesn't, it checks for the MovementComponent and returns the MovementComponents velocity.

So I guess that your MovementComponent isn't setting the Velocity variable.

more ▼

answered May 08 '17 at 10:13 AM

avatar image

DennyR
1.1k 31 12 47

avatar image brianempson May 08 '17 at 04:20 PM

Thank you, this makes sense, my movement class has nothing to calculate velocity built into it.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question