Hello I am trying to move AI using ACharacters AIController class. It runs the behavior tree but it says the path is invalid even tho I have set the path to be just meter away from the character!
Critter.h:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "BehaviorTree/BehaviorTree.h"
#include "Components/SphereComponent.h"
#include "GameFramework/Character.h"
#include "Perception/PawnSensingComponent.h"
#include "Critter.generated.h"
UCLASS()
class LVL_RUSALKA_API ACritter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
ACritter();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="AI")
UBehaviorTree* BehaviorTree;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="AI")
UPawnSensingComponent* PawnSensingComponent;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UFUNCTION()
void PawnSighted(APawn* pawn);
};
Critter.cpp:
// Fill out your copyright notice in the Description page of Project Settings.
#include "Critter.h"
#include "AIController.h"
// Sets default values
ACritter::ACritter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
PawnSensingComponent = CreateDefaultSubobject<UPawnSensingComponent>("Pawn Sensing");
PawnSensingComponent->SightRadius = 60;
PawnSensingComponent->SensingInterval = 0.25f;
PawnSensingComponent->OnSeePawn.AddDynamic(this, &ACritter::PawnSighted);
}
// Called when the game starts or when spawned
void ACritter::BeginPlay()
{
Super::BeginPlay();
AAIController* aiController = Cast<AAIController>(GetController());
aiController->RunBehaviorTree(BehaviorTree);
}
// Called every frame
void ACritter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ACritter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
void ACritter::PawnSighted(APawn* pawn)
{
FString message = TEXT("Saw Actor ") + pawn->GetName();
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, message);
//UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
}
Behavior tree task:
H:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "BehaviorTree/Tasks/BTTask_BlackboardBase.h"
#include "BTTask_FollowWaypoints.generated.h"
/**
*
*/
UCLASS()
class LVL_RUSALKA_API UBTTask_FollowWaypoints : public UBTTask_BlackboardBase
{
GENERATED_BODY()
public:
UBTTask_FollowWaypoints(const FObjectInitializer& ObjectInitializer);
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory);
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Waypoints")
TArray<FVector> Waypoints;
};
CPP:
// Fill out your copyright notice in the Description page of Project Settings.
#include "BTTask_FollowWaypoints.h"
#include "AIController.h"
#include "GameFramework/CharacterMovementComponent.h"
UBTTask_FollowWaypoints::UBTTask_FollowWaypoints(const FObjectInitializer& ObjectInitializer)
{
bCreateNodeInstance = true;
NodeName = "Pathfinding";
}
EBTNodeResult::Type UBTTask_FollowWaypoints::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
FPathFollowingResult result = OwnerComp.GetAIOwner()->MoveTo(Waypoints[0]);
if(result.Code == EPathFollowingResult::Type::Success)
{
UE_LOG(LogTemp, Warning, TEXT("Waypoint arrived to : %f"), Waypoints[0].X);
}
else if(result.Code == EPathFollowingResult::Type::Blocked)
{
UE_LOG(LogTemp, Warning, TEXT("Waypoint blocked to : %f %f %f"), Waypoints[0].X, Waypoints[0].Y, Waypoints[0].Z);
}
else if(result.Code == EPathFollowingResult::Type::Aborted)
{
UE_LOG(LogTemp, Warning, TEXT("Waypoint aborted to : %f %f %f"), Waypoints[0].X, Waypoints[0].Y, Waypoints[0].Z);
}
else if(result.Code == EPathFollowingResult::Type::Invalid)
{
UE_LOG(LogTemp, Warning, TEXT("Waypoint invalid to : %f %f %f"), Waypoints[0].X, Waypoints[0].Y, Waypoints[0].Z);
}
else if(result.Code == EPathFollowingResult::Type::OffPath)
{
UE_LOG(LogTemp, Warning, TEXT("Waypoint offpath to : %f %f %f"), Waypoints[0].X, Waypoints[0].Y, Waypoints[0].Z);
}
return EBTNodeResult::Succeeded;
}
It keeps showing me the result of Invalid and character is standing still. Someone please help!