x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

How to setup detection in a sphere?

So i'm trying to detect enemies within a certain radius of my AI. To do this i'm using a BT Service that calls OverlapMulti() to get all of the objects within a certain radius. It then checks if each object inherits a class called IDamageable and then checks if they are on the same team or not. If all goes well it determines that they are on opposite teams and can be damaged and attacks it. For some reason though most of the time the AI doesn't get a target. It will be right next to an enemy and just sit there. After a while sometimes one of them will finally detect an enemy and attack but sometimes it doesn't happen at all. I'm using the ECC_Pawn trace channel and made sure to set that on all enemies that are being checked but it's almost like the OverlapMulti() isn't picking up those objects. I've tried almost everything I can think of at this point and am still not having any luck. Let me know if there's any other information that would be helpful, thanks!

Here is my code to get a target:

 void UBTSCheckForTargets::TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds)
 {
     Super::TickNode(OwnerComp, NodeMemory, DeltaSeconds);
 
     if (ownerUnit)
     {
         TArray<AActor*> actorsToIgnore;
         actorsToIgnore.Add(ownerUnit);
         FVector start = ownerUnit->GetActorLocation();
         float radius = 720.0f;
         TArray<FOverlapResult> outHits;
         ECollisionChannel traceChannel = ECC_Pawn;
 
         bool hitOrNot = UGlobalDefinitions::OverlapSphere(actorsToIgnore, outHits, start, radius, traceChannel);
 
         // Loop through all of the hits
         for (int32 i = 0; i < outHits.Num(); ++i)
         {
             
             // Check to make sure the hit actor can be damaged
             IDamageable* damageableTarget = Cast<IDamageable>(outHits[i].GetActor());
             if (damageableTarget)
             {
                 
                 // Check to make sure its not friendly
                 if (damageableTarget->GetTeam() != ownerUnit->team)
                 {
                     // Get the key for our targetObject
                     targetKey.CacheSelectedKey(BBAsset);
                     FBlackboard::FKey targetObject = targetKey.GetSelectedKeyID();
 
                     blackboard->SetValue<UBlackboardKeyType_Object>(targetObject, outHits[i].GetActor());
                     return;
                 }
                 // Else keep looping until we find a valid hit
             }
         }
     }
 }

And here is the OverlapSphere function:

 // C++ Sphere Overlap Test
 bool UGlobalDefinitions::OverlapSphere(TArray<AActor*>& ActorsToIgnore, TArray<FOverlapResult>& OutHits, const FVector& Location, const float Radius, ECollisionChannel TraceChannel)
 {
 
     FCollisionQueryParams TraceParams(FName(TEXT("OverlapMulti Trace")), false);
     TraceParams.bTraceComplex = false;
     TraceParams.bReturnPhysicalMaterial = false;
     TraceParams.AddIgnoredActors(ActorsToIgnore);
 
 
     // Get World Source
     TObjectIterator<APlayerController> ThePC;
     if (!ThePC)
     {
         return false;
     }
 
     // Draw debug lines
     //const FName TraceTag("DebugLines");
     //ThePC->GetWorld()->DebugDrawTraceTag = TraceTag;
     //TraceParams.TraceTag = TraceTag;
 
     return ThePC->GetWorld()->OverlapMulti(OutHits, Location, FQuat(), TraceChannel, FCollisionShape::MakeSphere(Radius), TraceParams, FCollisionResponseParams(ECollisionResponse::ECR_Overlap));
 }
Product Version: Not Selected
Tags:
more ▼

asked Apr 08 '15 at 05:50 PM in C++ Programming

avatar image

ckchessmaster
67 12 14 17

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

Truthfully, I think you're better off using something like this...

https://docs.unrealengine.com/latest/INT/API/Runtime/AIModule/Perception/UPawnSensingComponent/index.html

Let us know if it works for you. :)

more ▼

answered Apr 08 '15 at 06:14 PM

avatar image

Mark James G
534 44 25 52

avatar image ckchessmaster Apr 09 '15 at 09:34 PM

Thanks! Yeah that seems like a much better approach. I may actually try and use the AIPerception system as in the long term I can do more with it.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question