Move large AI close to player

 avatar
unknown
c_cpp
a year ago
4.0 kB
7
No Index
#pragma once

#include "CoreMinimal.h"
#include "BehaviorTree/BTTaskNode.h"
#include "BTTask_ProjectToNavigation.generated.h"

UCLASS()
class THIRDPERSONMP_API UBTTask_ProjectToNavigation : public UBTTaskNode
{
	GENERATED_BODY()

public:
    UBTTask_ProjectToNavigation();

    virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
    virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;

protected:
    UPROPERTY(EditInstanceOnly)
    FBlackboardKeySelector m_targetKey;

    UPROPERTY(EditInstanceOnly)
    FBlackboardKeySelector m_resultKey;

    UPROPERTY(EditAnywhere)
    FVector m_projectionExtent = FVector(500.f, 500.f, 500.f);
private:
};

#include "Ai/BehaviorTree/Task/BTTask_ProjectToNavigation.h"

#include "NavigationSystem.h"
#include "AIController.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "BehaviorTree/Blackboard/BlackboardKeyType_Vector.h"
#include "BehaviorTree/Blackboard/BlackboardKeyType_Object.h"

UBTTask_ProjectToNavigation::UBTTask_ProjectToNavigation()
{
    NodeName = "Project To Navigation";

	m_targetKey.AddObjectFilter(this, GET_MEMBER_NAME_CHECKED(UBTTask_ProjectToNavigation, m_targetKey), AActor::StaticClass());
	m_targetKey.AddVectorFilter(this, GET_MEMBER_NAME_CHECKED(UBTTask_ProjectToNavigation, m_targetKey));

	m_resultKey.AddVectorFilter(this, GET_MEMBER_NAME_CHECKED(UBTTask_ProjectToNavigation, m_resultKey));
}

void UBTTask_ProjectToNavigation::InitializeFromAsset(UBehaviorTree& Asset)
{
    Super::InitializeFromAsset(Asset);

    if (UBlackboardData* blackboardAsset = GetBlackboardAsset())
    {
        m_targetKey.ResolveSelectedKey(*blackboardAsset);
        m_resultKey.ResolveSelectedKey(*blackboardAsset);
    }
}

EBTNodeResult::Type UBTTask_ProjectToNavigation::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
    UBlackboardComponent* blackboard = OwnerComp.GetBlackboardComponent();
    if (!blackboard)
    {
        return EBTNodeResult::Failed;
    }

    FVector rawLocation = FVector::ZeroVector;
    const TSubclassOf<UBlackboardKeyType> keyType = m_targetKey.SelectedKeyType;

    if (keyType == UBlackboardKeyType_Object::StaticClass())
    {
        UObject* object = blackboard->GetValueAsObject(m_targetKey.SelectedKeyName);
        const AActor* actor = Cast<AActor>(object);
        if (!actor)
        {
            return EBTNodeResult::Failed;
        }
        rawLocation = actor->GetActorLocation();
    }
    else if (keyType == UBlackboardKeyType_Vector::StaticClass())
    {
        rawLocation = blackboard->GetValueAsVector(m_targetKey.SelectedKeyName);
    }
    else
    {
        return EBTNodeResult::Failed;
    }

    UNavigationSystemV1* navSys = FNavigationSystem::GetCurrent<UNavigationSystemV1>(GetWorld());
    if (!navSys)
    {
        return EBTNodeResult::Failed;
    }

    const AAIController* aiController = OwnerComp.GetAIOwner();
    const AActor* controlledActor = aiController ? aiController->GetPawn() : nullptr;
    if (!controlledActor)
    {
        return EBTNodeResult::Failed;
    }

    const INavAgentInterface* navAgent = Cast<INavAgentInterface>(controlledActor);
    const FNavAgentProperties& agentProps = navAgent
        ? navAgent->GetNavAgentPropertiesRef()
        : FNavAgentProperties();

    const ANavigationData* navData = navSys->GetNavDataForProps(agentProps);
    if (!navData)
    {
        return EBTNodeResult::Failed;
    }

    FNavLocation projected;
    const bool bSuccess = navSys->ProjectPointToNavigation(
        rawLocation,
        projected,
        m_projectionExtent,
        navData
    );

    if (!bSuccess)
    {
        return EBTNodeResult::Failed;
    }

    blackboard->SetValueAsVector(m_resultKey.SelectedKeyName, projected.Location);
    return EBTNodeResult::Succeeded;
}
Editor is loading...