0

I'm trying to convert the boid flocking script found here: http://wiki.unity3d.com/index.php?title=Flocking

To work in my 2D game, it works but the flock does not follow the target at all. the flock seems to just want to go right and up on about a 20 degree angle. How do I get the flock to chase the target or "Chasee" in this script?

For simplicity I've left most of the coordinates as Vector3 and just cast them to Vector 2 when I adjust he velocity.

using UnityEngine;
using System.Collections;

public class BoidController : MonoBehaviour
{
    public float minVelocity = 5;
    public float maxVelocity = 20;
    public float randomness = 1;
    public int flockSize = 20;
    public GameObject prefab;
    public GameObject chasee;

    public Vector3 flockCenter;
    public Vector3 flockVelocity;

    private GameObject[] boids;

    void Start()
    {
        boids = new GameObject[flockSize];
        for (var i=0; i<flockSize; i++)
        {
            Vector3 position = new Vector3 (
                Random.value *  GetComponent<BoxCollider2D>().bounds.size.x,
                Random.value *  GetComponent<BoxCollider2D>().bounds.size.y
                ) -  GetComponent<BoxCollider2D>().bounds.extents;

            GameObject boid = Instantiate(prefab, transform.position, transform.rotation) as GameObject;
            boid.transform.parent = transform;
            boid.transform.localPosition = position;
            boid.GetComponent<BoidFlocking>().SetController (gameObject);
            boids[i] = boid;
        }
    }

    void Update ()
    {
        Vector3 theCenter = Vector3.zero;
        Vector3 theVelocity = Vector3.zero;

        foreach (GameObject boid in boids)
        {
            theCenter = theCenter + boid.transform.localPosition;
            theVelocity = theVelocity + (Vector3) boid.GetComponent<Rigidbody2D>().velocity;
        }

        flockCenter = theCenter/(flockSize);
        flockVelocity = theVelocity/(flockSize);
    }
}

And then the flocking behaviour

using UnityEngine;
using UnityEngine;
using System.Collections;

public class BoidFlocking : MonoBehaviour
{
    private GameObject Controller;
    private bool inited = false;
    private float minVelocity;
    private float maxVelocity;
    private float randomness;
    private GameObject chasee;

    void Start ()
    {
        StartCoroutine ("BoidSteering");
    }

    IEnumerator BoidSteering()
    {
        while (true)
        {
            if (inited)
            {
                GetComponent<Rigidbody2D>().velocity = GetComponent<Rigidbody2D>().velocity + (Vector2) Calc () * Time.deltaTime;

                // enforce minimum and maximum speeds for the boids
                float speed = GetComponent<Rigidbody2D>().velocity.magnitude;
                if (speed > maxVelocity)
                {
                    GetComponent<Rigidbody2D>().velocity = GetComponent<Rigidbody2D>().velocity.normalized * maxVelocity;
                }
                else if (speed < minVelocity)
                {
                    GetComponent<Rigidbody2D>().velocity = GetComponent<Rigidbody2D>().velocity.normalized * minVelocity;
                }
            }

            float waitTime = Random.Range(0.3f, 0.5f);
            yield return new WaitForSeconds (waitTime);
        }
    }

    private Vector3 Calc()
    {
        Vector3 randomize = new Vector3 ((Random.value *2) -1, (Random.value * 2) -1, (Random.value * 2) -1);

        randomize.Normalize();
        BoidController boidController = Controller.GetComponent<BoidController>();
        Vector3 flockCenter = boidController.flockCenter;
        Vector3 flockVelocity = boidController.flockVelocity;
        Vector3 follow = chasee.transform.localPosition;

        flockCenter = flockCenter - transform.localPosition;
        flockVelocity = flockVelocity - (Vector3) GetComponent<Rigidbody2D>().velocity;
        follow = follow - transform.localPosition;

        return (flockCenter + flockVelocity + follow * 2 + randomize * randomness);
    }

    public void SetController (GameObject theController)
    {
        Controller = theController;
        BoidController boidController = Controller.GetComponent<BoidController>();
        minVelocity = boidController.minVelocity;
        maxVelocity = boidController.maxVelocity;
        randomness = boidController.randomness;
        chasee = boidController.chasee;
        inited = true;
    }
}
JNYRanger
  • 6,829
  • 12
  • 53
  • 81
Early73
  • 473
  • 3
  • 7
  • 23
  • Are you working on a top down game? – Eissa Sep 18 '15 at 19:45
  • No its a sidescroller / platform type – Early73 Sep 18 '15 at 20:10
  • Curious about whether your vector2 casting is causing the issue. What i mean is whether or not the game is set along the correct axis. – Eissa Sep 18 '15 at 20:20
  • I wouldn't rule it out but I can't find the root of the problem. I've rewritten it with Vector2D's rather than casts and I have exactly the same problem. also changing the target and swarm centre velocity seem to have pretty much no effect. regardless the swarm travels at a 45 degree ange for infinity. – Early73 Sep 19 '15 at 00:54

1 Answers1

0

I was using local position on the chase and the boid when calculating the follow direction and they are children of different objects. should have been

Vector3 follow = chasee.transform.position;
follow = follow - transform.position;
Early73
  • 473
  • 3
  • 7
  • 23