I wanted to post this here for others as I spent some time trying to figure out how to make AI using DetourCrowd avoid running into the player.
First, you need to be using C++. The way I handled this was to go to Tools > New C++ Class, and make an Actor Component. Then in the component, you want the .h file to inherit from ICrowdAgentInterface, like this. I named my component PlayerCrowdAgentInterface:
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Navigation/CrowdManager.h"
#include "Navigation/CrowdAgentInterface.h"
#include "PlayerCrowdAgentInterface.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class AAYOURPROJECTNAME_API UPlayerCrowdAgentInterface : public UActorComponent, public ICrowdAgentInterface
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UPlayerCrowdAgentInterface();
FVector GetCrowdAgentLocation() const;
FVector GetCrowdAgentVelocity() const;
void GetCrowdAgentCollisions(float& CylinderRadius, float& CylinderHalfHeight) const;
float GetCrowdAgentMaxSpeed() const;
protected:
// Called when the game starts
virtual void BeginPlay() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
virtual void InitializeComponent();
};
And in the .cpp file:
#include "PlayerCrowdAgentInterface.h"
// Sets default values for this component's properties
UPlayerCrowdAgentInterface::UPlayerCrowdAgentInterface()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
// ...
}
// Called when the game starts
void UPlayerCrowdAgentInterface::BeginPlay()
{
Super::BeginPlay();
UCrowdManager* CrowdManager = UCrowdManager::GetCurrent(this);
if (CrowdManager)
{
ICrowdAgentInterface* IAgent = Cast<ICrowdAgentInterface>(this);
CrowdManager->RegisterAgent(IAgent);
}
}
// Called every frame
void UPlayerCrowdAgentInterface::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
// ...
}
void UPlayerCrowdAgentInterface::InitializeComponent()
{
Super::InitializeComponent();
}
FVector UPlayerCrowdAgentInterface::GetCrowdAgentLocation() const
{
return GetOwner() ? GetOwner()->GetActorLocation() : FVector::ZeroVector;
}
FVector UPlayerCrowdAgentInterface::GetCrowdAgentVelocity() const
{
return GetOwner() ? GetOwner()->GetVelocity() : FVector::ZeroVector;
}
void UPlayerCrowdAgentInterface::GetCrowdAgentCollisions(float& CylinderRadius, float& CylinderHalfHeight) const
{
if (GetOwner()) {
GetOwner()->GetSimpleCollisionCylinder(CylinderRadius, CylinderHalfHeight);
}
}
float UPlayerCrowdAgentInterface::GetCrowdAgentMaxSpeed() const
{
return 300;
}
Build then in UE attach the component to your player character.