Enabling DetourCrowd on Player Character for Avoidance with CrowdManager

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.

3 Likes

Thanks Lot.Does this work with pawn Class as well?

I’m trying to add this component, but both these includes aren’t found and it won’t build.
I’m in UE 5.5 (I know its a preview, but I’m just trying to test player avoidance).
Is it possible they changed something in 5.5?
Thanks :smiley:

I fixed the includes by adding the full path.

But it still has two errors in the cpp file.

I did a rebuild and it failed to compile with these errors.

Any help would be appreciated.

I was helped on Unreal Source Discord.

I add “AIModule” to my build.cs
image

And changed the includes back to

It now will compile