Looking at your code you already have your range which is BestDistSq. For now your range is 3.402823466e+38F which is pretty big but if you expose it as a UPROPERTY(EditAnywhere) you can edit it in your controller BP
so that sounds to be a really heavy process. try some other ways like using “AI Move To” or “Ray tracing” then you can play with distance and many other options.
I do use tracing in my weapon class but not in my controller. I also use a move to, in my behaviour tree for the bot. Will try what zimzimdz suggested first. Would be interested how you use tracing in the bot class though.
I have already written some functions on my bot that traces toward the player and if hit the player and if the length of that trace equals a specific number then the bots start chasing the player.
these are my functions:
I commented some lines of my code for you.
I hope it be helpful
void AEnemyBot::See()
{
FVector EyeLocation = GetMesh()->GetSocketLocation("Eye"); // Eye is socket on head of Bot to use as start_trace
FVector Start_Trace = EyeLocation;
FVector End;
ASwatCharacter* Swat = Cast<ASwatCharacter>(UGameplayStatics::GetPlayerCharacter(this, 0));
if(Swat)
{
FVector End_Trace = Swat->GetActorLocation(); // here I used the location of my player as end of trace(End_trace) so the bot always traces toward player.
End = End_Trace;
}
const FHitResult Impact = Detect(Start_Trace, End); // it calls Detect() function.
Process(Impact, Start_Trace, End); // it calls process() function.
}
FHitResult AEnemyBot::Detect(FVector Start_Trace, FVector End_Trace)
{
FCollisionQueryParams TraceParams(FName(""), true, this);
TraceParams.bTraceAsyncScene = true;
TraceParams.bReturnPhysicalMaterial = true;
TraceParams.bTraceComplex = true;
TraceParams.AddIgnoredActor(this);
FHitResult Hit(ForceInit);
GetWorld()->LineTraceSingleByChannel(Hit, Start_Trace, End_Trace, TRACE_WEAPON, TraceParams);
DrawDebugLine(this->GetWorld(), Start_Trace, End_Trace, FColor::Blue, true, 1000, 10.f);// it draws a blue line and shows the trace
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Black, "Detecting");
return Hit;
}
void AEnemyBot::Process(const FHitResult & Impact, const FVector & Orgin, const FVector End)
{
const FVector EndPoint = Impact.GetActor() ? Impact.ImpactPoint : End;// here calculate the end_trace again and sees if the trace hit the player or something else in its way something like a wall. if hit something the end point would be the impact point.
DrawDebugLine(this->GetWorld(), Orgin, EndPoint, FColor::Yellow, true, 1000, 15.f);// draws a yellow line to say, hey i have hit something in my way
const FVector Length = Orgin - EndPoint;// here calculates the length of the trace by subtracting the start_trace(orgin) with Endpoint.
ASwatCharacter* Swat = Cast<ASwatCharacter>(Impact.GetActor());
if (Swat && Length.Size()<1500 )// here we say if that length equals 1500 means that bot is seeing us.
{
GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Blue, "You are seen"); ////*****
IsChasing = true;
Chase(); /// this is a task
}
else
{
GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Blue, "You ran away"); // if that length increases or you go behind a wall the bots can not see you.
IsChasing = false;
}
}
Sorry I’m still trying to understand quite a bit in Unreal so my questions are probably stupid. How has the chase been done? Do I still need the chase as I have a BTService blueprint which follows the player once an enemy has been found?
Ok thank you for your help, much appreciated, I have implemented your code, with the chase commented out at the moment. Currently nothing happens or appears. So still figuring it out.
for those function like chase() that you don’t know about you can just print a message like"chasing is happening"
in my code chase() is a UFUNCTION(BlueprintImplementableEvent) that can be implemented in blueprint and called in c++.
for the forth parameter of this function you need to define it in your “project name.h”
GetWorld()->LineTraceSingleByChannel(Hit, Start_Trace, End_Trace, TRACE_WEAPON, TraceParams);
so go to your “project name.h” copy this there: #define TRACE_WEAPON ECC_GameTraceChannel1
Can I ask? hehe. Sorry I think I’m getting mixed up as I’m use to doing it in the AIController rather than the AICharacter. I also originally set up a service which executes the SearchForEnemy. Then in my behaviour tree on the select I use the service which executes searchForEnemy. If any of that makes sense? Then I use a Move To Enemy. So I switched the service to execute “See” Instead. Expecting it to work.