AI Perception change line-trace destination

In the examples below the small tiny beam is blocking sight between the AI entirely. Stairs and other height-difference have the same problem which is even worse:

The small beam is blocking the single raytrace performed by AI Perception. Also when players/enemies walk on stairs they can often not see each other and many other cases where this will not work. I know I can change the eyesight on the sourcepoint of the trace. But there does not seem to be a way of changing the destination point of the raytrace (I checked the internal code, uses GetActorLocation() everywhere and non-overrideable), which is quiet bad unless I overlooked something.

On top of that there seems to be only 1 raytrace. Which is weird because the internal code shows that there is a variable limiting the amount of raytraces to 6 per frame. But only 1 is performed? How can I tell the AI Perception AISense_Config to perform 3 traces (one to the GetActorLocation(), one to the bottom of the capsule and one to the top of capsule)?

My current code:

PerceptionComp = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("AIPerceptionComponent"));

SenseSightConfig = CreateDefaultSubobject<UAISenseConfig_Sight>(TEXT("SenseSightConfig"));
PerceptionComp->OnPerceptionUpdated.AddDynamic(this, &ABaseEnemy::OnSense);

PerceptionComp->SetDominantSense(SenseSightConfig->GetSenseImplementation());

SenseSightConfig->SightRadius = 9000.0f;
SenseSightConfig->LoseSightRadius = (SenseSightConfig->SightRadius + 20.0f);
SenseSightConfig->PeripheralVisionAngleDegrees = 90.0f; // 90.0f equals 180 degrees. Bug?
SenseSightConfig->DetectionByAffiliation.bDetectEnemies = true;
SenseSightConfig->DetectionByAffiliation.bDetectNeutrals = true;
SenseSightConfig->DetectionByAffiliation.bDetectFriendlies = true;
PerceptionComp->ConfigureSense(*SenseSightConfig);

I really hope it is possible to add more traces because otherwise the whole AI-perception is useless in most games due to height differences, stairs, railings, and other tiny objects.

Have you considered simply subclassing the AI Perception Component and overriding the problem behaviour with your own desired changes? It seems easier to me than trying to work around the issue!

Yes I have considered it (but for the AISenseSight because that is I believe the one that has the code) but not done it because I was/am still hoping that I missed something. I can not imagine that Epic designed an AI-perception that is only capable of using 1 line-trace and also being incompatible with stairs and ‘just about everything’ that you commonly encounter in a 3D game. It will only work on flat games with either no objets or objects that are as tall as the tallest player/enemy + delta height, which is rare.

I can’t really go back to pawnsensing because pawnsensing is missing even more critical features + it can be marked as deprecated any release from now.

Luckily the Update() method is marked virtual so I can override it. The bad news is that they didn’t split it into smaller functions, thus the Update method is HUGE (~75% of the entire AISenseSight class). But okay I could just copy-paste the whole thing and change what I need. It is however very ugly and upgrading to newer version of UE4 is gonna cause problems for this code later on for sure. I probably have to put my custom code in methods inside of that huge overwritten function to make upgrading easier later on.

But again I’m still hoping for a better alternative.

After an attempt to implement the solution you mentioned (since I didn’t see any other way) I quickly figured out that I have to override at least the following 2 classes: UAISense_Sight & UAISenseConfig_Sight.

UAISense_Sight is sadly not ‘very nicely coded’. UAISense_Sight::Update() is so huge and not split into smaller methods… I have to copy-paste the whole thing.

On top of that the:

#include "AIModulePrivate.h"

is not available for my derived class. It is throwing all sorts of DLL errors and such. Could it be that it is not exposed somehow? Must I add something to the build-file maybe?

And aside from the above it’s a real ‘mess’ to fix this. Because of this ‘messiness’ and because (I estimate) at least 8 out of 10 games are gonna need this I assume that this is a missing feature.

Also I noticed that there is no method to retrieve the sensed friendly-actors and no method to get the neutral-actors. Looking at the internal code I see that the code doesn’t even make a difference between Neutral & Friendly. There is only hostile and non-hostile…

All by all this looks buggy/incomplete.

Found it in the IAISightTargetInterface. If we only had documentation…

Indeed there is a virtual function CanBeSeenFrom() in IAISightTargetInterface, but it does not give you the location of the target. So you have to write your own Update() (to actually give the location of the target) in the end anyway…
Or am I missing something?

CanBeSeenFrom() is of course implemented on the target-actor (it won’t work anywhere else anyway, you can check this by using a breakpoint inside the CanBeSeenFrom). Meaning that you can get the location of the target simply by:

GetActorLocation(); // or  this->GetActorLocation();

Ah okey! Makes sense, thanks :slight_smile:

Having the same problem here, Napoleonite. Could you be a little bit more specific on how to override the function “CanBeSeenFrom”?

Thanks a lot!