AI using Move To with Blackboard Vector behaves inconsistently compared to Move To Actor

Hi everyone,

I’m implementing a combat slot system where enemies move to a calculated position around the player instead of directly to the player’s location.

My BT Service calculates a Vector called ChaseTarget every 0.1 seconds using:

  • Player location
  • Player velocity prediction
  • Slot offset (Front, Back, Left, Right, etc.)

The Move To task uses this ChaseTarget Vector.

If I change the Move To node to use PlayerActor instead, everything works perfectly.

With Move To(PlayerActor):

  • AI detects me instantly.
  • AI continuously chases me.
  • AI attacks correctly.

With Move To(ChaseTarget Vector), I get many inconsistent problems:

  • Sometimes it works once after launching the game, but after restarting PIE it behaves completely differently.
  • Sometimes AI detects me very late even when I’m standing directly in front of it.
  • Sometimes it detects me, starts moving, then immediately loses me.
  • Sometimes it walks toward me, then suddenly stops.
  • Sometimes it stops around 3–4 meters away and won’t come closer until I move.
  • Sometimes it only starts moving again if I move a little.
  • Sometimes it goes to the front of the player instead of the assigned combat slot (for example it should move behind me).
  • Sometimes it stands in front of me without attacking until I move slightly backward.
  • After attacking, it sometimes runs to a random location, stops there, and never moves again until I move.
  • Different enemies behave differently. One may stop chasing while others still move, but they also stop several meters away.

Current setup:

  • UE5 C++
  • AI Perception (Sight)
  • Behavior Tree
  • Blackboard
  • PlayerActor (Object)
  • ChaseTarget (Vector)
  • BT Service updates ChaseTarget every 0.1 seconds

Things I’ve checked:

  • PlayerActor is valid.
  • ChaseTarget is updating continuously.
  • Blackboard key type is Vector.
  • Move To node uses the ChaseTarget key.
  • If I switch the Move To node back to PlayerActor, every issue disappears.

I’ve also been advised to project ChaseTarget onto the NavMesh using ProjectPointToNavigation(), but I haven’t confirmed whether that’s the root cause yet.

Has anyone experienced this before or knows what could cause Move To(Vector) to behave so differently from Move To(Actor)?

I’m happy to share my BT Service code, AI Controller, Behavior Tree, or a video if that helps.

Moving to predicted locations is always tricky because if you were moving when NPC decided to move, but stopped before it got to the bb loc, it’s going to try to finish moveto and run right past you. Or in revere, if you were stationary when it saw you and service predicted you’d still be there but you move, it will stop short. I had a similar problem with bodyguard NPCs walking right behind me then shooting me in back of head when combat started. Tried path prediction and ended with crab-like movement every time player pawn stopped or started moving. I solved it by duct taping a hidden dummy actor to a spring arm on my player (pointing right), and told the BT to follow that actor. Probably not the most efficient solution, but you could attach a formation of hidden child actors to your player, make an interface to set/query a bool called “isclaimed” or some such on them, then have your slot selection service get child actors of player and query/claim a slot.

And maybe add a trigger box to the slot actor to have it set/clear the bool on begin/end overlap events. And probably a looping timer to periodically clear claimed bool in case an NPC gives up or dies before it gets there.

As for why, I believe the generic moveto behavior only uses the vector it was fed when fired, whereas with an actor as the target, it will respect the track moving goal option on the behavior.

Alternatively (and surely more efficiently) you could use EQS to generate a ring of points around a target context and have enemies move to the closest one of those. Would probably want to start by sending them straight to target initially, then have a selector with a distance check to start doing the formation around target when they’re roughly in range. Otherwise EQS will start firing needlessly while they’re off in Ohio somewhere.

I made my ranged enemies circke around targets with an EQS query like this:

The target context simply gets blackboard from querier, gets its TargetActor key as an object casts that to actor and returns a single actor result.