Search Unity

Flocking avoidance algorithm help

Discussion in 'Scripting' started by CoffeeConundrum, Aug 23, 2016.

  1. CoffeeConundrum

    CoffeeConundrum

    Joined:
    Dec 30, 2013
    Posts:
    46
    Hey there,

    I've been working on a 2D space shooter for a game jam idea that and working. Simple premise, the player has to defeat the waves of enemies to progress.

    I've managed to make my enemies follow the player without any issues, however, what I noticed was that the enemies don't interact very well with one another and I would like to make it so that they would avoid one another. I started to look into the flocking algorithm which Craig Reynolds boids works off of to find a solution to my issue.

    While I *think* I understand it, I'm struggling on how to convert this into c# script for my enemies.
    I understand I'm going to have to have a controller which keeps track of each enemy that has been spawned.
    From there, each enemy needs to know if they are going to bump into anyone in the future of the same type and if so , change its direction of travel.

    I looked into using casting a ray out to the front of the enemy ships however I struggled with this as well.

    Anyone able to help explain / guide me through this? Many thanks in advance.
     
  2. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,716
    While I am no expert on group movement or anything you can start by getting your raycasting to work correctly. You could also alternatively use a shape cast or overlap check to validate your ship's bounds at a location. The ray may not hit something, but the ship's bounds would.

    Your cast will need an origin, a direction, and distance.

    So for a Raycast:

    Your origin is the ship's center. The direction is shipTransform.right (im assuming your ships face down the X axis?). The distance to check (if checking every frame), is your ship's current velocity, because that is how far it will move next frame. You can supply the LayerMask so that only specific layers will stop the raycast.
    https://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html

    For an overlap check (circle shape for example):

    The center would be forward, where the ship will be next frame.

    So you can do "shipTransform.position + (shipTransform.right * shipVelocity)", giving you your ship's position next frame.

    Then you can supply a radius, perhaps your ship's SpriteRenderer or Collider half-width or radius. For a box you would use full width. LayerMask would detect only the colliders on the layers defined in that mask.

    https://docs.unity3d.com/ScriptReference/Physics2D.OverlapCircle.html


    Shape casts:
    https://docs.unity3d.com/ScriptReference/Physics2D.CircleCast.html
    https://docs.unity3d.com/ScriptReference/Physics2D.BoxCast.html

    When in doubt, use Debug.Draw to show what you're doing.
     
  3. MV10

    MV10

    Joined:
    Nov 6, 2015
    Posts:
    1,889
    Not trying to be a jerk here, but have you simply searched the forum for "boids"? There have been a bazillion implementations and discussions here over the years.
     
  4. CoffeeConundrum

    CoffeeConundrum

    Joined:
    Dec 30, 2013
    Posts:
    46
    I have but unfortunately nothing for 2D. Everything I've seen so far has been for 3D implementations which is where I'm having difficulty with.
     
  5. CoffeeConundrum

    CoffeeConundrum

    Joined:
    Dec 30, 2013
    Posts:
    46
    @jeffreyschoch Thanks for taking the time to explain this. Think I have got a better idea now of what I'm needing to do.
    Shall go about implementing this now :)
     
    LiterallyJeff likes this.
unityunity