Reading back through this I realize (and it won’t let me edit my original post) I forgot to mention my proposed system doesn’t support PathFinding. It circumvents it and creatures will often run into various obstacles.
However, I don’t want to leave anyone high and dry with no solution, so what I’ve been using since is a sort of “MoveTo” actor to control the movement of the creatures. Here’s the rundown:
Create an actor class (I called mine simply BP_MoveTarget
) and spawn one of these on BeginPlay in your AI Controller or pawn. Store a reference to it. Whenever you want your creature to move to a location, have it move to the MoveTarget actor instead, and manipulate the location of the MoveTarget. What I’ve found works best for creatures is:
- On the first tick of the move, store the creature’s current rotation in a new variable (such as
CurrentRotation
). - Every frame get a look at rotation between the creature and target location and store this in another new variable (such as
TargetRotation
). - Interpolate
CurrentRotation
toTargetRotation
. - Next, convert the
CurrentRotation
to a forward vector (CurrentForwardVector
) and project the location a distance along that vector. I’ve found that 2,000 - 3,000 units is a decent distance, but configure to your needs (this math would essentially beCreatureActorLocation + CurrentForwardVector * ProjectionDistance
). - Finally, set the MoveTarget’s location to this vector each frame.
This will yield a more realistic creature movement with “pathfinding”. The pathfinding can sometimes not match the desired movement occasionally, but the creature won’t be running into objects.
This system is considerably more complex than the original. I implemented mine in C++ and had to take various other steps to ensure it worked properly. I figure most can use this as a starting point and diagnose those issues in their own way, but I can share my solutions to various problems if needed.
If you’re somewhat of a perfectionist, I suggest looking into various methods to replace/compliment this system, such as proper pathfinding (like the suggested A*) or using a custom movement component (I use this, but it is possible to make your own with some extensive C++ knowledge). However, this works for me thus far, so no need yet to dive into custom pathfinding.
Hopefully this proves a little more useful!