Turning radius for AI?

I have some AI creatures in my game that walk around but when they start moving towards their next target, they just snap towards it instead of rotating around to face their target and then start walking towards it. Is there a way I could add a turning radius to my AI?

You can tweak the CharacterMovementComponent to your liking :

Annotation 2020-07-29 004424.png

That makes it start to move in a direction and the mesh rotation will be lagged behind the actual movement. I want an actual curve. This is what your solution looks like, but I want something that looks like this:
Annotation 2020-07-28 185632.png
https://forums.unrealengine.com/core/image/gif;base64
​
The black line is the path the AI will follow and the red dot is the AI, which is facing directly to the right but curves towards the path as it travels down it.

You could use “Find look at rotation”, and plug the yaw into yaw of SetActorRotation. The “start” is your enemy, and “target” is the player.

Wouldn’t that just do make it snap to face towards the player? I want it to follow a curve to turn around.

I’m using it currently and the enemy rotates to face me.


https://imgur.com/a/l5DyNCg

I’m looking for a way for the AI to follow curve to turn towards the player. Not get snapped to look in the direction of the player. Take a look at the image I posted above to see what I’m trying to do.

Ah, sorry. I saw the image and din’t understand it, you want the enemy to still have velocity while turning, some kind of arc. I don’t have any way to help you with that… =/

Yeah thats exactly what I’m looking for.

Maybe you could do something with RInterp To, I think Interp speed, is what sets the rotation?

The info window also says that it gives a “nice smooth feeling when rotating to target” So just add velocity and reduce the look at rotation?

Yeah but that doesn’t solve the issue of calculating a circle to turn around on.

This sounds pretty complex.

Just talking here, because I could absolutely not do this, but sounds like you’ll need to have some sort of algorithm to determine a curve between 2 points. You’ll then need to generate points along that curve in 3d space.

Again, no idea how to actually do this though.

hm okay. I’ll have to do some research on an algorithm to do that.

Even if I find an algorithm for that, how could I implement it? I’m using black boards for my AI and I have no idea how I would create this.

Hate to necro, but I found a solution that works for my uses and given the lack of answers to questions just like this, figured I should share in case it could help anyone else. (NOTE: I’m using a Behavior Tree Task for my logic, however, it shouldn’t be that different in any other blueprint)

The problem is Unreal’s default response to AI Movement is “Turn in Place”, where the actor would rotate almost instantaneously to face its target (or it would rotate slowly while moving directly towards the target, which is almost worse). This works great for upright things, like humans, but not so much for things that are longer than taller, like most animals (this is because animals don’t really strafe like humans can, they mostly move forward or backward and rotate the front of their body to turn, much like a car). Instead, they need a “Turn Radius” system, a way where they can follow the path of a circle until they were pointing at the desired location. Unreal doesn’t have support for this out of the box, so the only solution is to create one, which is easier than it sounds. Basically you have to recreate functions like the “MoveTo” to use a “Turn Radius” system.

Step 1: Off of event tick, get the look at rotation from the pawn to the target location. Use only the Z-axis of the look at, otherwise it will rotate and move the pawn incorrectly. Then, interpolate the pawn’s current rotation with the look at rotation, and set the interpolated rotation as the pawn’s new rotation. This first step makes it so the pawn rotates in intervals each frame, instead of instantaneously. Also, you can use a Turn Rate variable as I have that connects to the “Interp Speed” of the RInterpTo node. This allows you to control how quickly each pawn can rotate in your game (if used in a Behavior Tree Task, I would suggest making it a “Blackboard Key Selector” type so it can easily be set by the pawn).

Step 2: After the actor’s rotation is set, simply add movement input to the pawn on its Forward Vector. This moves the pawn forward slightly after every rotation and produces an arc. An added side-effect is that the turning radius automatically adapts to the pawn’s speed, making the arc larger the faster it moves, which is more realistic.

Step 3: After moving the pawn, a check is performed to see if the pawn has reached a distance away from the target that is considered acceptable and, if so, finishes the process with success. Otherwise, everything repeats.

In addition, I have a timeout on the Behavior Tree when this task is called, in case the turning radius causes the pawn to never reach its target.

This doesn’t allow you to determine an exact radius the creature should rotate around. For that, you would need a specific mathematical algorithm to place multiple target locations along a path, as far as I could tell. However, for my case (and hopefully others), this solution works just fine.

Hope this helps!

1 Like

I tried getting the usual navigation path, then use circle tangents and navrays to modify it into a path that counts for turning radius. Sort of worked though I stopped for different reasons (I was making my own movement component as I was trying to use box collision for a semi-physics pawn but doing proper replication takes too long so I gave up).

This way it doesn’t matter if the character movement can snap to direction, as long you do the navigation right and not allow it to move without one you are set.

Since this was first google showed me it is not necroposting, leave me alone! :slight_smile:

EDIT: I read about A* navigation that takes gradual turning into account but not sure where…

Hi it is called Hybrid A*, and it is used for Car/vehicle pathfinding:

So this can also be used somehow for animals tooo…

1 Like

This is actually kind of genius! Thanks for sharing. What I did now is using an RInterpConstant. This way I get perfect circles with a constant rotation rate.

1 Like

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:

  1. On the first tick of the move, store the creature’s current rotation in a new variable (such as CurrentRotation).
  2. Every frame get a look at rotation between the creature and target location and store this in another new variable (such as TargetRotation).
  3. Interpolate CurrentRotation to TargetRotation.
  4. 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 be CreatureActorLocation + CurrentForwardVector * ProjectionDistance).
  5. 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!