How to make enemies avoid other enemies' attack hitboxes

Hoping anyone can point me towards what to research/learn to achieve this.

I have an enemy character with a melee attack. It’s able to walk forward during the melee attack. (i.e. a sword swinging around)

I want to make it so when other enemies move around, they actively avoid being hit by their fellow enemies.

I’d like to attach a box collision in the enemy character which encapsulates the entire area the melee attack covers (the entire area the sword swings around in).

Where I’m stuck at, is how to get enemies to avoid this box collision, but the owner of the box collision to ignore its own box collision.

Any ideas? Thank you!

First, your box should be “overlap” not “block” if what you’re trying to do is to drive the behavior of the actor, e g, give the actor the knowledge to back up or side step, rather than just “push” on other actors.

Second, in the “on component overlap” event callback, you are given a reference to the actor that overlaps the box. Simply check whether the actor is yourself in there.

How would you drive the behavior of the actor? What system do I use to do this?

Currently my enemy AI uses a blackboard MoveTo node to move towards the player actor. How do I make it so during it’s pathfinding, it avoids these collision boxes of other enemies?

There are tons of ways of making an AI avoid other AIs.

There’s built-in avoidance:

However, making the AI “do avoidance” while also “use simple MoveTo to get to the player” isn’t going to work very well.

Perhaps the best thing you can do in this case, is figure out how many NPCs will fit around the player, while still having reach to the player. Then allocate “slots” and have each NPC claim a “slot” and move to that “slot.”

For example, if 3 characters fit, there might be slots for “in front,” “rear right” and “rear left.” The first NPC would claim the “in front” slot, the next one would claim “rear right” and the final one “rear left.” You might also want to not claim slots that are currently blocked by terrain/walls.
The character would then “Move To” the location of the slot, as relative to the player, rather than “Move To” the player.

Note that this has nothing to do with collision – this has to do with designing behaviors and assets and actions that all go well together.

What else other than MoveTo should be used? The tutorial you linked itself used MoveTo. Is there a more advanced node I should be using?

The slots system seems interesting. Is that built into Unreal? I don’t see slots mentioned anywhere in what you linked. Is that something I have to code myself?

As you mentioned, this still doesn’t quite explain how to solve my problem. I appreciate your tips so far! But if I have an enemy that has a flamethrower for instance. I don’t want other enemies running into the flames and dying to enemy friendly fire.

You should MoveTo the slot position, not the player position.

Avoidance works as long as the obstacles are “along the path,” but won’t make the NPCs arrange themselves well for an actual melee fight.

Slots are not built into Unreal, because this is a particular design you may or may not want to use. If NPCs only ever fight the player, you could have them look for some slot allocation interface on the player character; if they can fight each other, you might want to put that interface on any potential target.

If the size of the meelee swipe (which was your initial request) is 3 meters in diameter, then you need to arrange the slots more than 3 meters from each other, in a circle around the player, such that they can still reach the player themselves. Whether you can fit 2 or 3 or 4 depends on how far forward the attach reaches compared to sideways.

For an area of attack, where you could have things like grenades on the floor just as well as flame thrower area of effect, you might be better modeling it as “areas to avoid,” which would be some invisible actor geometry your flamethrower NPC would spawn in the world where he expects to fire, and any NPC would treat this as an obstacle and avoid it. Whether this is a “dynamic navmesh obstacle” or something more specific, depends on what your gameplay needs. These kinds of system tend to be quite game specific (together with “cover” and “flanking” and all the rest of the hard-to-build AI behaviors.)

This is why it’s hard – you usually have to do it yourself, because every game (and every attack modality WITHIN every game) ends up with their own requirements, and they all interact.

I see, I figured as much I’d have to code the slot system myself.

I’ve looked into dynamic navmesh obstacle before, is there a way to set them up so I can dynamically set selected NPC to ignore these areas? So not all NPC’s avoid the area.

Back to the flamethrower AI example, I’d like the AI to move forward towards player as it blasts fire. If I place a navmesh obstacle there, all other enemies will know to avoid it, but includes the flamethrower AI as well, causing it to get stuck.

I also wish to include vision into the mix, where AI’s that can see the navmesh obstacle avoids it, while those that can’t ignore it (allowing player to trick AI’s into getting hit by friendly fire).

It doesn’t look like the built in dynamic navmesh obstacle allows any of this to be possible. Do I have to scrap unreal’s built in navigation system and write a custom pathfinding system?

You’d need to use different navmesh classes for this (which I think ends up being essentially different navmeshes under the covers,) and the “dynamic navigation obstable” flag doesn’t distinguish between which classes it affects, so you’d have to code that, too, which I think must be done in C++ – the necessary hooks aren’t available in Blueprint.

That sounds like a fun game mechanic! :slight_smile: I think the reason we don’t see it more in games, is that it requires really tricky implementation to actually work. Here’s hoping you make the next big genre buster, kind-of how Thief made Stealth a thing!

1 Like

I see… Well thank you for all the help the encouraging words!

I think you are looking for UCrowdFollowingComponent.

I figured out a working solution! It’s not the most natural solution, nor performance efficient, and has limitations, but it’s 100% BP. I’m making heavy use of RVOAvoidance, the Avoidance Group, Groups to Avoid, and Groups to Ignore.

To start I made an empty character blueprint. (I called it “BP_AvoidSphereBase”) This BP will be used as the “Avoid area”. Disable all collision in the capsule component. They won’t be necessary:

Check use RVOAvoidance, set Avoidance Weight to 1. The consideration radius will require fine tuning.
image

Drag the avoid area BP into your enemy BP so they are added as child actor components. Put them at roughly where you want other enemies to avoid when this enemy performs an attack.

Set the enemy BP to also use RVOAvoidance but set Avoidance Weight to 0.

Now we have to set each enemy to use a unique RVO group. This is where the limitation comes in. This system would only work with up to 32 enemies attacking the player simultaneously, as BP only exposes 32 RVO groups. Pawns using the same RVO group will ignore each other’s avoid areas.

Anyways, I use this function to set the RVO groups:
What it does is it’ll ignore it’s own RVO but avoid all other RVO.

The idea is you give each enemy in your level a unique RVO (0-31), then run that function to set the enemy character and their avoid area children character’s character movement component RVO group to that.

For enemies that are spawned in at run time. I’m using this temporary solution until I build a smarter system (BP_MobBase is the parent BP of all enemies in my project):
It finds all actors and their RVO groups, increments until it finds a group that no one is using, and outputs that. If none is found, it returns 31.

So finally, at run time, use the “Set Avoidance Enabled” node to dynamically enable/disable these avoid areas. Play around with the avoidance radius until it suits your needs.

As the avoid areas has no inherit collision, players and enemies can physically walk through them while they are active. Making it possible for enemies to be tricked into hitting each other.

I hope this small guide helps anyone that comes across this!

1 Like