0
\$\begingroup\$

I have a group of enemies that move together. I have them grouped around a point by setting their target to be a point at the center of the group. I have combined the "Seek" and "Separate" steering behaviors to achieve this. My issue stems from the fact that they all want to move to that point, effectively fighting for the center. (The separate steering behavior just has them doing this at a distance, and when trying to use the arrive steering behavior the same issue happens it's just slightly less pronounced, but has other side effects I don't want.) Is there any way I could group them like this without having them fight for the center? I don't want to have set positions as that would be unnatural looking and ill-fitting for my game. I also think a flow field would have the same issues (I'm not sure about that).

Note: The point moves, as this is for group movement.

\$\endgroup\$
1
  • \$\begingroup\$ I know this looks similar to several other questions, but none solve my issue and this seems different enough not to be a duplicate. \$\endgroup\$ – GameDungeon Jul 22 at 3:11
1
+50
\$\begingroup\$

Falloff with distance

Implement falloff with distance in your steering behaviours to make them do less when less relevant.

I assume your Seek and Separate behaviours each output a desired direction and weight that your enemies use to determine how to move. If you scale the weight by distance, then you can let the two behaviours balance each other out.

Seek scales inversely with distance to destination.

Separate scales proportionally with distance to other enemies.

function clamp(min, max, num)
    return num <= min and min or (num >= max and max or num)
end

function inverse_lerp(a, b, t)
    return (t - a)/(b - a)
end

function scale(min, max, val)
    val = clamp(min, max, val)
    local t = inverse_lerp(min, max, val)
    -- See easings.net for alternatives to this cubic curve.
    return t * t * t
end

Will give a curve like:

the influence curve for our scale function

Use 1 - scale(min, max, distance) to scale inversely.

That way your Seek will have no influence when the enemies are close to their target, only small influence when "close enough", and lots of influence when far away.

Influence threshold before action

Additionally, if your enemies look good stationary (ground units, units with standing idles, etc), you could set a threshold of influence before they move. This threshold could vary so it becomes higher when they're stationary to avoid jittering and lower when moving quickly to be more responsive.


When figuring this stuff out, I'd always recommend visualizing your data with graphs. Here's the love2d program that I used to generate that graph:

function love.draw()
    local pts = {}
    local size = 10000
    local min = 100
    local max = 200
    for x=0,size,1 do
      table.insert(pts, x + 50)
      table.insert(pts, 200 - 100 * scale(min, max, x))
    end
    love.graphics.points(pts)
    love.graphics.line(10, 200, 10, 100)
    love.graphics.line(10, 200, 20, 200)
    love.graphics.line(10, 100, 20, 100)
    love.graphics.print("0", 25, 190)
    love.graphics.print("1", 25, 100)
end
\$\endgroup\$
0
\$\begingroup\$

The answer to your question lies with the strategies employed in this short video by Game Endeavor...

https://www.youtube.com/watch?v=6BrZryMz-ac

Quote from Game Endeavor:

NOTE: I'm not using this as a replacement for path finding. The purpose of this is to control how the AI behaves in its local environment. ie avoid clumping together, strafe the player, flee from the player but don't get stuck on walls. NOT get from point a to point b.

The fact that it can avoid simple obstacles is just an added bonus that came about naturally from this system, but not the primary way of avoiding them. Without proper path finding, the ai will get stuck if there is a wall between it and its target. However, you can combine this with a pathfinder, if you have it seek along the path instead of directly at its target. :)

\$\endgroup\$
1
  • 1
    \$\begingroup\$ This answer would be better if it at least summarized the main lesson you hope a reader will glean from that video. That way, even if the video ever goes offline or is unreachable for a particular user, they'll still be able to understand the strategy you're recommending here. \$\endgroup\$ – DMGregory Jul 29 at 9:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.