Change AI Perception Target

Hi. AI perception usually targets the middle of a character(First person capsule). So when the player is behind objects like 100cm of height, AI cannot detect the player. How do I change the target to first-person camera? Thanks.

P.S My project is blueprint only

Some things require C++ and this is one of them. Here’s a tutorial:

1 Like

Thank you. My project is blueprint only. Do I need to create my project from the beginning as c++ project?

Nope, you can just create a new C++ class as shown in the tutorial :blush:

Hi. I just added the code to newely created character class. I built it successfully, Now there is no detecting sphere when playing. Ai cannot detect me when he sees me.

// Fill out your copyright notice in the Description page of Project Settings.


#include "MyCharacter.h"

// Sets default values
AMyCharacter::AMyCharacter()
{
 	// 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;

}

// Called when the game starts or when spawned
void AMyCharacter::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void AMyCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

}

bool AMyCharacter::CanBeSeenFrom(const FVector& ObserverLocation, FVector& OutSeenLocation, int32& NumberOfLoSChecksPerformed, float& OutSightStrength, const AActor* IgnoreActor, const bool* bWasVisible, int32* UserData) const
{
	FName Name_AILineOfSight = FName(TEXT("TestPawnLineOfSight"));
	FHitResult HitResult;
	FVector SightTargetLocation = GetMesh()->GetSocketLocation("spine_02");

	AActor* actor = Cast<AActor>(HitResult.GetActor());

	bool hit = GetWorld()->LineTraceSingleByChannel(HitResult, ObserverLocation, SightTargetLocation, ECC_Visibility, FCollisionQueryParams(Name_AILineOfSight, false, IgnoreActor));

	if (!hit || (IsValid(actor) && actor->IsOwnedBy(this)))
	{
		OutSeenLocation = SightTargetLocation;
		OutSightStrength = 1;
		//return UAISense_Sight::EVisibilityResult::Visible;
		return true;
	}

	OutSightStrength = 0;
	return false;
}



I contacted “Code Like me” and he sent me the new code

for CLM_Character.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Perception/AISightTargetInterface.h"
#include "GameFramework/Character.h"
#include "CLM_Character.generated.h"

UCLASS()
class SHOOTLIKEME_API ACLM_Character : public ACharacter, public IAISightTargetInterface
{
	GENERATED_BODY()

public:
	// Sets default values for this character's properties
	ACLM_Character();

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;

	//virtual bool CanBeSeenFrom(const FVector& ObserverLocation, FVector& OutSeenLocation, int32& NumberOfLoSChecksPerformed, float& OutSightStrength, const AActor* IgnoreActor = NULL, const bool* bWasVisible = false, int32* UserData = NULL ) const;
	virtual UAISense_Sight::EVisibilityResult CanBeSeenFrom(const FCanBeSeenFromContext& Context, FVector& OutSeenLocation, int32& OutNumberOfLoSChecksPerformed, int32& OutNumberOfAsyncLosCheckRequested, float& OutSightStrength, int32* UserData = nullptr, const FOnPendingVisibilityQueryProcessedDelegate* Delegate = nullptr);
};

For CLM_Character.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "CLM_Character.h"

// Sets default values
ACLM_Character::ACLM_Character()
{
 	// 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;

}

// Called when the game starts or when spawned
void ACLM_Character::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void ACLM_Character::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void ACLM_Character::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

}

UAISense_Sight::EVisibilityResult ACLM_Character::CanBeSeenFrom(const FCanBeSeenFromContext& Context, FVector& OutSeenLocation, int32& OutNumberOfLoSChecksPerformed, int32& OutNumberOfAsyncLosCheckRequested, float& OutSightStrength, int32* UserData, const FOnPendingVisibilityQueryProcessedDelegate* Delegate)
{
	FName Name_AILineOfSight = FName(TEXT("TestPawnLineOfSight"));
	FHitResult HitResult; 
	FVector SightTargetLocation = GetMesh()->GetSocketLocation("neck_01");

	bool hit = GetWorld()->LineTraceSingleByChannel(HitResult, Context.ObserverLocation, SightTargetLocation, ECC_Visibility, FCollisionQueryParams(Name_AILineOfSight, true, Context.IgnoreActor));

	if (!hit || IsValid(HitResult.GetActor()) && HitResult.GetActor()->IsOwnedBy(this))
	{
		OutSeenLocation = SightTargetLocation;
		OutSightStrength = 1;
		return UAISense_Sight::EVisibilityResult::Visible;
	}

	OutSightStrength = 0;
	return UAISense_Sight::EVisibilityResult::NotVisible;
}

//bool ACLM_Character::CanBeSeenFrom(const FVector& ObserverLocation, FVector& OutSeenLocation, int32& NumberOfLoSChecksPerformed, float& OutSightStrength, const AActor* IgnoreActor, const bool* bWasVisible, int32* UserData) const
//{
//	FName Name_AILineOfSight = FName(TEXT("TestPawnLineOfSight"));
//	FHitResult HitResult; 
//	FVector SightTargetLocation = GetMesh()->GetSocketLocation("neck_01");
//
//	bool hit = GetWorld()->LineTraceSingleByChannel(HitResult, ObserverLocation, SightTargetLocation, ECC_Visibility, FCollisionQueryParams(Name_AILineOfSight, true, IgnoreActor));
//
//	if (!hit || IsValid(HitResult.GetActor()) && HitResult.GetActor()->IsOwnedBy(this))
//	{
//		OutSeenLocation = SightTargetLocation;
//		OutSightStrength = 1;
//		return true;
//	}
//
//	OutSightStrength = 0;
//	return false;
//}

Now it works like a charm. Thanks