Whole formation strafe while pursuing player

Grailmoth

New member
I have purchased behavior designer, and the movement and formations packs. I am trying to achieve an effect where the enemies chase a character while in formation, but I don't wan't the formation to rotate while pursuing. I would rather have the whole formation "strafe" side to side.

Say the player can move along a line. I want to formation to form facing the direction of that line, and then continue to face that line as the move to stay in front of the player while they move left and right. Is there a way to achieve that with this asset, to lock the rotation of the formation?

Additionally, is there a way for have the enemies hold formation while they pursue the player? The formation seems to get dissolved whenever I am pursuing.
 

Justin

Administrator
Staff member
When the agents are initially moving into the formation they are required to start off at the correct rotation. This is done with RotateTowards within FormationGroup OnUpdate. This isn't built in but when the formation starts you could set the update rotation to false on the NavMeshAgent which would then prevent the agents from rotating.

By holding formation do you mean they are becoming staggered? Are you able to reproduce it within the demo scene?
 

Grailmoth

New member
I actually do want the agents within the formation to rotate themselves to face the correct direction. What I don't want is for the shape of the formation to rotate. I want the triangle/wedge to stay pointed a certain direction. Is there a way to control to rotation of the formation shape?

I am able to reproduce the "losing formation" effect in the demo scene when I increase all of the speeds.

I am using the column formation. It starts off with these settings:
Screen Shot 2019-03-26 at 5.55.00 AM.png

and I have increased them to these settings on all agents:

Screen Shot 2019-03-26 at 5.59.47 AM.png

which results in this behavior (click for gif to play):
OddStartingBehaviorAndMovement.gif
The formation does not stay tight, and some of the agents seem to wobble when getting into formation. The problem is exacerbated when the target is moving.

Watching the gif, it seems like some agents keep overshooting their position, and then having to correct themselves.
 

Grailmoth

New member
For what it's worth, I am trying to use the formations pack to arrange space ships into formations and fly them around a transparent 2D navmesh plane. I want them have behavior similar to drones, where all members of the formation move pretty in sync with each other.
 

Justin

Administrator
Staff member
I actually do want the agents within the formation to rotate themselves to face the correct direction. What I don't want is for the shape of the formation to rotate. I want the triangle/wedge to stay pointed a certain direction. Is there a way to control to rotation of the formation shape?
Ah, there isn't an option for this. For this I would create a new formation task that overrides TargetPosition and returns a new position that has each agent keeping the same rotation.
The formation does not stay tight, and some of the agents seem to wobble when getting into formation. The problem is exacerbated when the target is moving.
What is happening is that the agents are missing their target destination so they do a wobbling behavior until they reach it. If you increase the distance you'll also need to increase the stopping distance on the navmeshagent.
 

Grailmoth

New member
I'll look into creating a new formation then. Is there documentation on how to do that somewhere?

Doing a quick search I see some documentation on conditional tasks and action tasks, but no formation task. I can get started looking at those two, and maybe that will give me enough to start. If you have formation documentation too, that would be great.

-edit- nevermind. I found it here - https://opsive.com/support/documentation/behavior-designer-formations-pack/new-formation-task/

I saw another post talking about stopping distance, and I tried that, but I guess I just need to fiddle with the value more. It seems like increasing the stopping distance gets to a spot faster, but it isn't always a perfect formation. Which I guess makes sense, since stopping distance increases the acceptable radius for where the agent can stop.

Is there a way to set the stopping distance to zero, but have them slow down as they approach their target spot so they don't overshoot?
 

Justin

Administrator
Staff member
Is there a way to set the stopping distance to zero, but have them slow down as they approach their target spot so they don't overshoot?
This is more on the NavMeshAgent side of things since the Formations Pack just sets the destination and then expects the agent to move to that destination. I just looked at the NavMeshAgent API and it looks like there is an acceleration value, but I don't know if that affects the stopping distance as well. If it doesn't you could do a check for the remaining distance and if it's less than a specified value change the speed of the agent.
 

Grailmoth

New member
Upping the acceleration worked pretty well. Thanks!

I'm trying to write my own formation, and what I want to achieve is an arc that always faces away from Vector3.zero. What I've done is to take your code for the arc formation and modified the TargetPosition method as you said. After getting the leaderTransform, I added a line that makes the leader look away from Vector3.zero and then calculates the position for the agent

C#:
 protected override Vector3 TargetPosition(int index, float zLookAhead)
        {
            // Alternate between the left and right sides of the leader. If convex then add PI so the agents form the back side of the circle.
            // Convex arcs will also increase their relative z position so the agents are ahead of the leader.
            var radians = /*Math you wrote in Arc.cs*/;
            var leaderTransform = leader.Value == null ? transform : leader.Value.transform;
            leaderTransform.rotation = Quaternion.LookRotation(2 * leaderTransform.position - Vector3.zero, Vector3.up); //I added this
            return leaderTransform.TransformPoint(/*Math you wrote in Arc.cs*/);
        }
And it works for getting the agents in the right spots.
Screen Shot 2019-03-28 at 7.31.46 AM.png

but the formation never moves on to the next step of moving towards the target position, and the task stays in the "Running" state indefinitely. What is needed to get the formation move towards the target position after getting to their formation positions?

Screen Shot 2019-03-28 at 7.39.52 AM.png

If I remove the line I added, the code is the same as Arc.cs and it does complete the task, but I don't get the formation orientation that I want.
 

Justin

Administrator
Staff member
If you place a breakpoint within FormationGroup.OnUpdate and are looking at the leader object (so leader.Value is null) where does it get stuck at? When all of the agents are in position the move status should change from MoveStatus.Formation to MoveStatus.Full.
 

Grailmoth

New member
So, it seems like waitForAgent gets stuck as true.

There is a for loop starting on line 324
C#:
for (int i = 1; i < formationAgents.Count; ++i) {
    if (!pathStarted[i]) {
        pathStarted[i] = formationAgents[i].HasPath;
    }
    if (!pathStarted[i] || (moveStatus[0] == MoveStatus.Wait && moveStatus[i] == MoveStatus.Full) || moveStatus[i] == MoveStatus.Catchup) {
        waitForAgent = true;
    }
}
And it starts at index 1, so the leader (at index zero) never seems to get his pathStarted updated to his HasPath value.

In the second if statement, moveStatus of the leader (at index 0) is set to MoveStatus.Wait, which means waitForAgent is always true.

Additionally, in this bit of code, starting line 334
C#:
if (waitForAgent) {
    moveStatus[0] = inFormation ? MoveStatus.Formation : MoveStatus.Wait;
} else {
    moveStatus[0] = MoveStatus.Full;
}
inFormation always seems to be false, so moveStatus[0] stays as MoveStatus.Wait.

For what it's worth, only the leader still has their move status as wait. Everyone else has it set to full.
 
Last edited:

Grailmoth

New member
Additional info: I tried setting WaitToMove to false on all my agents and that didn't help. They still make the formation but don't go anywhere.

If I delete all agents accept for the leader, then he moves towards the target immediately.
 
Last edited:

Grailmoth

New member
I sent you a message with a link to a unitypackage where I have the problem reproduced.

Watch the difference between the arc task and my controlled arc task, I'm also noticing that with my task the non-leader agents do not rotate to match the rotation of the leader, but with the arc task they do. Is that somehow getting broken by the fact that I am setting the rotation of the leader as part of the TargetPosition method?

-edit- The fact that they weren't rotating didn't have anything to do with it. I had stopping distance set at zero (which is the default I believe) and upping it to .1 fixed the rotation thing. They all rotate to match the leader now, but still don't start moving towards the target transform.
 
Last edited:

Justin

Administrator
Staff member
I'm not able to take a look at the package right now but there are two different parts to updating the inFormation variable. The part that you posted about relates to the leader, whereas the status will actually change for the followers within the second big if block. It sounds like the the variable is never being set to true within:

Code:
inFormation = formationAgent.RotateTowards(leader.Value.transform.rotation) || leaderMoveStatus != MoveStatus.Wait;
Since you are using a different type of rotation you may want to override rotate towards to always return true.
 
Top