Well, I have tried to reproduce your problem. Everything works fine. I have UE4.21
Here is my code, just fill up the holes in your code
ZControllerAI.h
#pragma once
#include "CoreMinimal.h"
#include "AIController.h"
#include "ZControllerAI.generated.h"
UCLASS()
class MOVEMENTTEST_API AZControllerAI : public AAIController
{
GENERATED_BODY()
public:
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
AActor* ActorToMove;
virtual void Tick(float DeltaSeconds) override;
};
ZControllerAI.cpp
#include "ZControllerAI.h"
#include "DrawDebugHelpers.h"
void AZControllerAI::Tick(float DeltaSeconds)
{
if (ActorToMove != nullptr) {
auto res = MoveToActor(ActorToMove, 10);
//auto res = MoveToLocation(FVector(0,0,0), 10);
auto pathComp = GetPathFollowingComponent();
if(pathComp != nullptr) {
auto path = pathComp->GetPath();
auto world = GetWorld();
if (path.IsValid()) {
auto points = path->GetPathPoints();
for (int32 pInd = 1; pInd < points.Num(); pInd++) {
DrawDebugLine(world, points[pInd - 1].Location, points[pInd].Location, FColor::Green, false, -1, 0, 5);
}
}
}
}
}
ZMovementComponentReq.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PawnMovementComponent.h"
#include "ZMovementComponentReq.generated.h"
UCLASS()
class MOVEMENTTEST_API UZMovementComponentReq : public UPawnMovementComponent
{
GENERATED_BODY()
virtual void RequestDirectMove(const FVector& MoveVelocity, bool bForceMaxSpeed) override;
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
};
ZMovementComponentReq.cpp
#include "ZMovementComponentReq.h"
#include "DrawDebugHelpers.h"
void UZMovementComponentReq::RequestDirectMove(const FVector & MoveVelocity, bool bForceMaxSpeed)
{
Super::RequestDirectMove(MoveVelocity, bForceMaxSpeed);
Velocity.Z = 0;
Velocity = Velocity.GetClampedToMaxSize(100.0f);
UE_LOG(LogTemp, Log, TEXT("MoveVel: %s"), *Velocity.ToString())
}
void UZMovementComponentReq::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction * ThisTickFunction)
{
FVector deltaMove = Velocity * DeltaTime;
if (deltaMove.IsNearlyZero()) return;
auto rot = deltaMove.GetSafeNormal().Rotation();
FHitResult hit;
SafeMoveUpdatedComponent(deltaMove, rot, true, hit);
if (hit.IsValidBlockingHit()) {
SlideAlongSurface(deltaMove, 1.f - hit.Time, hit.Normal, hit);
}
UE_LOG(LogTemp, Warning, TEXT("Velocity: %s"), *deltaMove.ToString());
auto loc = UpdatedComponent->GetComponentLocation();
DrawDebugLine(GetWorld(), loc, loc + Velocity, FColor::Red, false, -1, 0, 5);
}
ZNavPawn.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "ZNavPawn.generated.h"
class UZMovementComponentReq;
class UStaticMeshComponent;
class UCapsuleComponent;
UCLASS()
class MOVEMENTTEST_API AZNavPawn : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
AZNavPawn();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UZMovementComponentReq* ZMoveComp;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UStaticMeshComponent* MeshComp;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UCapsuleComponent* CapsuleComp;
virtual UPawnMovementComponent* GetMovementComponent() const override;
};
ZNavPawn.cpp
#include "ZNavPawn.h"
#include "Components/CapsuleComponent.h"
#include "Components/StaticMeshComponent.h"
#include "ZMovementComponentReq.h"
#include "Engine/CollisionProfile.h"
// Sets default values
AZNavPawn::AZNavPawn()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>("Capsule");
RootComponent = CapsuleComp;
CapsuleComp->InitCapsuleSize(35, 90);
CapsuleComp->SetCollisionProfileName(UCollisionProfile::Pawn_ProfileName);
CapsuleComp->CanCharacterStepUpOn = ECB_No;
CapsuleComp->SetShouldUpdatePhysicsVolume(true);
CapsuleComp->bCheckAsyncSceneOnMove = false;
CapsuleComp->SetCanEverAffectNavigation(false);
CapsuleComp->bDynamicObstacle = true;
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
MeshComp->SetupAttachment(CapsuleComp);
MeshComp->SetCanEverAffectNavigation(false);
ZMoveComp = CreateDefaultSubobject<UZMovementComponentReq>("MovementComp");
ZMoveComp->UpdatedComponent = CapsuleComp;
}
// Called when the game starts or when spawned
void AZNavPawn::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AZNavPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void AZNavPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
UPawnMovementComponent * AZNavPawn::GetMovementComponent() const
{
return ZMoveComp;
}