Multiple AI characters has problems colliding with actors

I have this project where the AI Hunters are supposed to hunt for apples until they have reached the amount of 2 apples. However when I try to start they often have problems collecting the food infront of them because of some collider problem.

Whenever the scanners starts scanning, theyre supposed to find the nearest apple inside that scanning area which you can see in the video I sent.

Heres a pic of the colliding blueprint, I have 2 different colliding checkers to make sure both the body and the colliders of the character actually touches the apple.

Heres a video to show the problem. Numbers above their head are how many apples theyve eaten. Ive seen hunters eat 2 but the main point is that they cant touch the apple that good

INFO: Those 3 Hunters are spawned from the HunterCharacterClass. The apples are made from the same mechanic just that they are stationary actors with no AI from the AppleActor.

Hey @ExpectedYou,

Can you share the collision profiles for your hunters and apples? Also, does this same behavior occur when only one hunter AI is in the level? They may have an issue navigating around each other. If the issue is resolved by only including one hunter AI in the level, consider using a Detour Crowd Controller. Detour Crowd is a great way for multiple AI to navigate around each other, especially while moving. More information on Detour Crowd can be found here.

I hope this information helps, and good luck!

When only one hunter is in the level the problem doesnt occur, Ive already tried this before to check that my colliders actually works

Here are the collision profiles:

Hunter:

Apple:

Activating Detour Crowd Controller didnt help at all ;-;

Hello @ExpectedYou ,

Looks like the problem you are facing is related to the collisions between the hunters and the apples, what I would try to do is instead of using the Hit event (when 2 actors block each other), use the Overlap event.

What I suspect is happening, is that the collisions (the physics part) are happening before the event gets triggered, so in your case, the hunters are pushing away the apples (and the apples are pushing away the hunters) before actually counting as an OnHit.

So, TL;DR: change the responses of the hunters to the PhysicsBody (what the apples are according to the images you sent) to Overlap, then change the response of the apples to Pawn to Overlap. And then instead of using that function on the OnHit event, use it on the OnOverlapBegin

Hope this helps!

This gave me different results each time I played.
One crashed because of an infinite loop,
one got too many and by that I mean they got 2+ instead of 1+ collected apple values
and lastly one was the same as it was before.

This is how the code looks like right now:

I couldnt add overlap checker for the sphere since it wouldnt let me play because of an infinite loop

Can you send a screenshot or video showing this loop? Maybe it can be avoided.

This could be solved by adding a BeginDestroy() on the OnBeginOverlap event of the apple, be cautious to not reference the apple after destroying it.

I got another idea of what could be happening with the collisions, how are you moving the hunters to the apples? If you are using the MoveTo() on the controller, maybe it is a problem with the range that marks it as acceptable.

needs a FAIMoveRequest,

https://docs.unrealengine.com/4.27/en-US/API/Runtime/AIModule/FAIMoveRequest/

which has a float value AcceptanceRadius, which denotes the minimum distance between the target and the actor before marking as a successful move.

EDIT: I just noticed that on the blueprint of the overlap, the Equals (==) node is not connected to the Branch node. So right now if it overlaps with anything that it can overlap, it would mark it as the hunter eating the apple.

You could also instead of checking if the other actor is the apple that it went looking for, check if the OtherActor can be cast as an AClassOfTheApple, that way you can make sure that the hunter only picks up apples instead of the specific apple its following.

Video of the infinite loop:

It already gets destroyed as soon as it touches the apple; if thats what begindestroy does

I am using the Move To Location or Actor

I noticed that connection and fixed it :sweat_smile:

I am kinda new to the unreal engine, might you explain how I could do this one:

check if the OtherActor can be cast as an AClassOfTheApple

BeginDestroy gets called when the UObject (Actors are objects too, but are spawned in the world) is destroyed, to destroy an actor you have to call AMyActor->Destroy(). Objects will automatically be garbage collected when no active actors have a reference to them.

Sure, no problem! In c++ it would be something like this:

AAppleClass* Apple = Cast<AAppleClass>(OtherActor)
if(Apple)
{
  // OtherActor is an AAppleClass
}
else
{
  // OtherActor is not an AAppleClass
}

or

if(AAppleClass* Apple = Cast<AAppleClass>(OtherActor))
{
  // OtherActor is an AAppleClass
}
else
{
  // OtherActor is not an AAppleClass
}

or

AAppleClass* Apple = Cast<AAppleClass>(OtherActor)
if(IsValid(Apple))
{
  // OtherActor is an AAppleClass
}
else
{
  // OtherActor is not an AAppleClass
}

The blueprint equivalent to that would be:

If the cast fails, it will be a null pointer. So asking if it is valid should let you know if it is an Apple or not.

For the infinite loop thing, you could place breakpoints on the code or blueprint and it should tell you where it got stuck when on runtime. To place a breakpoint on a blueprint, you have to do this or press F9:

I didnt really understand how to convert AMyActor->Destroy() to blueprint code but what I did instead was to destroy the actor that was touched && could be casted to and that left me with no errors so I could only assume it was one of the right ways.

The cast to apple seem to have done its job :+1:

Some hunters still has issues now and some of them dont, heres a vid of that:

All right, that’s great to hear! Looks like there is only one thing missing, and that would be to adjust the AcceptanceRadius of the MoveTo function. To do that you have to change the node of MoveToLocationOrActor for a AIMoveTo function.

or

image

For this example I assumed it’s gonna move on the tick, you can set it whenever you want. They should both do the same, and now you have a new attribute which you can configure AcceptanceRadius, try setting it more close to the apples (reduce the number).

That’s great, I think this is the equivalent for what I’ve told you on blueprints

Im happy to say that IT WORKED!!!

Heres a vid:


EDIT: I also just realized that I got some errors too
“Attemted to access AppleActor_C_0 via property CallFunc_FindNearestActor_ReturnValue”
Which is here

Since the aimoveto was in the “on component begin overlap (scannerobject)” The AI moveto couldnt work there since it doesnt always go along with tickspeed; so what I had to do was to put a whileloop in my event tick and when the condition is true, it begins hunting, in this case: do the AI MoveTo as long as the condition is true each tick.

heres a quick blueprint example for what I did:

I’m glad it worked!

What you are doing there is a little weird, what it is doing is that whenever the hunter overlaps with something, then it asks the world for all the apples, then find the nearest and then assign it to FoundApple. What could be better is use The Other Actor attribute in the OnComponentBeginOverlap, that already gives you the apple that the hunter is touching, so there’s no need for it to ask the world about all the apples in the level. So after casting it to make sure that the hunter is indeed touching an apple and not another thing, then you can assign it to FoundApple.

The error you were having is due to the hunters trying to find apples, when there are not anymore. To avoid that you have to make some sanity checks, like for instance, checking if the arrays are empty or not (like the one returned by the get all actors of class function)

Your first solution was a bit hard for me to understand, If I got this correctly: Wouldnt the Hunters in the scene be trying to go for the platform that is underneath the hunters since it also collides with the hunters scanners?
I did this sort of section of blueprint code to find the nearest apple inside the scanners radius and assign it to the variable “foundapple”; the hunter is then supposed to catch that foundapple object. If I could do this better, would you please show me a blueprint/code example? I come from unity development so I hardly know how blueprint works :sweat_smile:

The error you were having is due to the hunters trying to find apples, when there are not anymore. To avoid that you have to make some sanity checks, like for instance, checking if the arrays are empty or not (like the one returned by the get all actors of class function)

I dont know how to check if ALL the apples in the class array are valid sadly but this is what I found as an alternative solution :smiley: :

EDIT: Unless you meant that I should check if every object in a class is valid in a forloop that checks arrays?

It should not, as it is colliding with a OnHit with the ground and not an OnBeginOverlap, that is because of the collision channels and if they are blocking or overlapping, this may help you understanding more about collisions in UE Collision Overview | Unreal Engine Documentation

What I meant is this, without needing to search for every apple every time the hunter overlaps with something.

I defined Grab Apple as this:

Additionally, if you want to check if an Array is empty, there is no need to check for all the elements that are inside that array.

You could use:

This checks if the first element is valid, if it is you know that the array is not empty, additionally you could do this:

This checks the number of elements inside the array, so that if it is greater than 0, then it is not empty.

To check if all the elements in an array are valid, it would be something like this:

Where it checks for all actors of class Apple in the world, then for each of them found, it will check if they are valid or not, and if it founds one apple that is not valid, it will interrupt the for each iterator.

1 Like

As this makes the characters find the fastest way to the apples, I did notice that they dont really go for apples that are inside the radius, they take whatever the closest apples are in the world.

Heres a vid:

Heres the blueprint, its the same as before just that it now prints whatever the found apples location is: