示例#1
0
    private void ApplySeparationBehavior(BoidAgent boid)
    {
        var tooCloseBoids = GetBoidsInRange(boid, _boidSettings.avoidanceRange);
        var avoidanceMove = GetAvoidanceMove(boid.transform.position, tooCloseBoids);

        ApplyAvoidanceMove(boid, avoidanceMove, _boidSettings.moveSpeed);
    }
示例#2
0
        public override Vector2 calculateGoalPosition(BoidAgent agent)
        {
//            return Vector2.zero;
            return((Cohesion(agent) * cohesionWeight + Alignment(agent) * alignmentWeight +
                    Avoidance(agent) * avoidanceWeight + RandomMove(agent) * randomWeight +
                    FearOfUnknown(agent) * fearOfUnknownWeight).normalized);
        }
示例#3
0
    public override Vector2 CalculateMove(BoidAgent agent, List <Transform> context, Boid boid)
    {
        // Handle data mismatch
        if (weights.Length != behaviours.Length)
        {
            throw new UnityException("Length mismatch in behaviour array");
        }

        // Set up move
        Vector2 move = Vector2.zero;

        // Iterate through behaviours
        for (int i = 0; i < behaviours.Length; ++i)
        {
            Vector2 partialMove = behaviours[i].CalculateMove(agent, context, boid) * weights[i];

            if (partialMove != Vector2.zero)
            {
                // Clamp the movement to the weight of the behaviour
                if (partialMove.sqrMagnitude > weights[i] * weights[i])
                {
                    partialMove.Normalize();
                    partialMove *= weights[i];
                }
                move += partialMove;
            }
        }
        return(move);
    }
示例#4
0
    public override Vector2 CalculateMove(BoidAgent agent, List <Transform> context, Boid boid)
    {
        // If there are no neighbors, do not calculate the move
        if (context.Count == 0)
        {
            return(Vector2.zero);
        }

        // Add all points and average
        Vector3 avoidanceMove = Vector3.zero;
        int     boidsToAvoid  = 0;

        foreach (Transform neighbor in context)
        {
            if (Vector2.SqrMagnitude(neighbor.position - agent.transform.position) < boid.SqrAvoidanceRadius)
            {
                boidsToAvoid++;
                avoidanceMove += agent.transform.position - neighbor.position;
            }
        }

        if (boidsToAvoid > 0)
        {
            avoidanceMove /= boidsToAvoid;
        }

        return(avoidanceMove);
    }
示例#5
0
    private Quaternion GetAverageAlignment(BoidAgent boid, Collider[] neighbouringBoids)
    {
        Quaternion averageAlignmnent = new Quaternion();

        //TODO: continue scripting
        return(averageAlignmnent);
    }
示例#6
0
    private void ApplyCohesionBehavior(BoidAgent boid)
    {
        var neighbouringBoids  = GetBoidsInRange(boid, _boidSettings.neighborsRange);
        var cohesionMoveVector = GetCohesionMove(boid.transform.position, neighbouringBoids);

        Debug.DrawRay(boid.transform.position, cohesionMoveVector);
        ApplyCohesionMove(boid, cohesionMoveVector, _boidSettings.moveSpeed);
    }
示例#7
0
    private Collider[] GetBoidsInRange(BoidAgent boid, float range)
    {
        var boidsInRange = Physics.OverlapSphere(boid.transform.position, range, boidsLayerMask);

        boidsInRange = boidsInRange.Where(val => val.gameObject != boid.gameObject).ToArray();
        Debug.Log(boidsInRange.Length);
        return(boidsInRange);
    }
示例#8
0
 private void Awake()
 {
     for (int i = 0; i < numberOfAgents; i++)
     {
         Vector3   pos       = transform.position + Random.insideUnitSphere * spawnRadius;
         BoidAgent agentInst = Instantiate(agent, pos, Quaternion.identity);
         agentInst.transform.forward = Random.insideUnitSphere;
     }
 }
示例#9
0
        private Vector2 FearOfUnknown(BoidAgent agent)
        {
            Vector2 centerOffset    = Vector2.zero - (Vector2)agent.transform.position;
            float   radiusCloseness = centerOffset.magnitude / radius;

            if (radiusCloseness > 0.9f)
            {
                return(radiusCloseness * radiusCloseness * centerOffset);
            }
            return(Vector2.zero);
        }
 protected void SpawnBoids()
 {
     for (int i = 0; i < _boidCount; i++)
     {
         Vector3 spawnPosition = transform.position + Random.onUnitSphere * _spawnRadius;
         // Debug.Log($"spawn position: {spawnPosition}");
         // Vector3 spawnPosition = spawnPos;
         boid = Instantiate(_boidPrefab, spawnPosition, Quaternion.identity);
         Boids.Add(boid);
     }
 }
示例#11
0
    // In order to get the neighbors boids, we can iterate through every boid in the scene
    // and check which are close to the current boid.
    // However we can use Unity's physics system to return all boids which collide with the current boid.
    List <Transform> GetNearbyBoids(BoidAgent agent)
    {
        List <Transform> context = new List <Transform>();

        Collider2D[] contextColliders = Physics2D.OverlapCircleAll(agent.transform.position, neighborRadius);
        foreach (Collider2D c in contextColliders)
        {
            if (c != agent.AgentCollider)
            {
                context.Add(c.transform);
            }
        }
        return(context);
    }
示例#12
0
        private Vector2 Avoidance(BoidAgent agent)
        {
            List <Transform> neighbors     = agent.fov.objectsInView;
            Vector2          avoidanceMove = Vector2.zero;

            if (neighbors.Count == 0)
            {
                return(avoidanceMove);
            }
            foreach (var neighbor in neighbors)
            {
                avoidanceMove += (Vector2)(agent.transform.position - neighbor.position);
            }
            avoidanceMove /= neighbors.Count;
            return(avoidanceMove);
        }
示例#13
0
        private Vector2 Alignment(BoidAgent agent)
        {
            List <Transform> neighbors     = agent.fov.objectsInView;
            Vector2          alignmentMove = Vector2.zero;

            if (neighbors.Count == 0)
            {
                return(agent.transform.up);
            }
            foreach (var neighbor in neighbors)
            {
                alignmentMove += (Vector2)neighbor.up;
            }
            alignmentMove /= neighbors.Count;
            return(alignmentMove);
        }
示例#14
0
    public override Vector2 CalculateMove(BoidAgent agent, List <Transform> context, Boid boid)
    {
        // Calculate the distance from the boid to the center of the circle
        // This circle corresponds with the center of the viewpoint
        Vector2 centerOffset = center - (Vector2)agent.transform.position;
        float   t            = centerOffset.magnitude / radius;

        if (t < radiusThreshold)
        {
            return(Vector2.zero);
        }
        else
        {
            return(centerOffset * t * t);
        }
    }
示例#15
0
 // Start is called before the first frame update
 void Start()
 {
     innovationIndexer = gameObject.AddComponent <InnovationIndexer>();
     for (int i = 0; i < numBoids; i++)
     {
         BoidAgent boidAgent = Instantiate(
             agentPrefab,
             density * numBoids * Random.insideUnitCircle,
             Quaternion.Euler(Vector3.forward * Random.Range(0f, 360f)),
             transform);
         boidAgent.name = "Boid" + i;
         const int numInputs  = 3;
         const int numOutputs = 2;
         boidAgent.genome = new Genome(numInputs, numOutputs, innovationIndexer);;
         agents.Add(boidAgent);
     }
 }
示例#16
0
        private Vector2 Cohesion(BoidAgent agent)
        {
            List <Transform> neighbors    = agent.fov.objectsInView;
            Vector2          cohesionMove = Vector2.zero;

            if (neighbors.Count == 0)
            {
                return(cohesionMove);
            }
            foreach (var neighbor in neighbors)
            {
                cohesionMove += (Vector2)neighbor.position;
            }
            cohesionMove /= neighbors.Count;
            cohesionMove -= (Vector2)agent.transform.position;
            cohesionMove  = Vector2.SmoothDamp(agent.transform.up, cohesionMove, ref currentVelocity, 0.5f);
            return(cohesionMove * 10);
        }
示例#17
0
    public override Vector2 CalculateVelocity(BoidAgent boid)
    {
        Vector2 separationMove = Vector2.zero;

        if (boid.Neighbours.Count == 0)
        {
            return(boid.transform.up);
        }

        foreach (BoidAgent neighbourBoid in boid.Neighbours)
        {
            if (Mathf.Abs(Vector2.Distance(boid.transform.position, neighbourBoid.transform.position)) < _separationRange)
            {
                separationMove += (Vector2)(boid.transform.position - neighbourBoid.transform.position);
            }
        }
        return(separationMove);
    }
    // Start is called before the first frame update
    void Start()
    {
        squareMaxSpeed        = maxSpeed * maxSpeed;
        squareNeighborRadius  = squareNeighborRadius * squareNeighborRadius;
        squareAvoidanceRadius = squareNeighborRadius * avoidanceRadiusMultiplier * avoidanceRadiusMultiplier;

        for (int i = 0; i < startingCount; i++)
        {
            BoidAgent newAgent = Instantiate(
                agentPrefab,
                Random.insideUnitCircle * startingCount * AgentDensity,
                Quaternion.Euler(Vector3.forward * Random.Range(0f, 360f)),
                transform
                );
            newAgent.name = "UnInfected: " + i;
            agents.Add(newAgent);
        }
    }
示例#19
0
    public override Vector2 CalculateMove(BoidAgent agent, List <Transform> context, Boid boid)
    {
        // If there are no neighbors, maintain current heading
        if (context.Count == 0)
        {
            return(agent.transform.up);
        }

        // Add all points and average
        Vector3 alignmentMove = Vector3.zero;

        foreach (Transform neighbor in context)
        {
            alignmentMove += neighbor.transform.up;
        }

        alignmentMove /= context.Count;

        return(alignmentMove);
    }
示例#20
0
 private void ApplyBoidBehavior(BoidAgent boid)
 {
     //Todo: optimize the algorithm
     if (separationBehavior)
     {
         ApplySeparationBehavior(boid);
     }
     if (cohesionBehavior)
     {
         ApplyCohesionBehavior(boid);
     }
     if (alignmentBehavior)
     {
         ApplyAlignmentBehavior(boid);
     }
     if (moveForwards)
     {
         ApplyForwardsMotion(boid);
     }
 }
    public override Vector2 CalculateVelocity(BoidAgent boid)
    {
        Vector2 cohesionMove = Vector2.zero;

        if (boid.Neighbours.Count == 0)
        {
            return(boid.transform.up);
        }

        foreach (BoidAgent neighbourBoid in boid.Neighbours)
        {
            cohesionMove += (Vector2)neighbourBoid.transform.position;
        }

        if (boid.Neighbours.Count > 0)
        {
            cohesionMove /= boid.Neighbours.Count;
        }

        return(cohesionMove);
    }
示例#22
0
    public override Vector2 CalculateMove(BoidAgent agent, List <Transform> context, Boid boid)
    {
        // If there are no neighbors, do not calculate the move
        if (context.Count == 0)
        {
            return(Vector2.zero);
        }

        // Add all points and average
        Vector3 cohesionMove = Vector3.zero;

        foreach (Transform neighbor in context)
        {
            cohesionMove += neighbor.position;
        }

        cohesionMove /= context.Count;

        // Create offset from agent position
        cohesionMove -= agent.transform.position;
        return(cohesionMove);
    }
    public override Vector2 CalculateVelocity(BoidAgent boid)
    {
        Vector2 alignmentMove = Vector2.zero;

        if (boid.Neighbours.Count == 0)
        {
            return(boid.transform.up);
        }

        foreach (BoidAgent neighbourBoid in boid.Neighbours)
        {
            alignmentMove += neighbourBoid.GetComponent <Rigidbody2D>().velocity;
        }

        if (boid.Neighbours.Count > 0)
        {
            alignmentMove /= boid.Neighbours.Count;
            alignmentMove -= boid.GetComponent <Rigidbody2D>().velocity;
        }

        return(alignmentMove);
    }
示例#24
0
 public abstract Vector3 CalculateMove(BoidAgent agent, List <Transform> context, Boid boid);
示例#25
0
 public override Vector2 calculateGoalPosition(BoidAgent agent) {
     var position = agent.transform.position;
     List<float> inputs = new List<float>{position.x, position.y, position.z};
     return agent.genome.Evaluate(inputs).normalized;
 }
示例#26
0
 /// <summary>
 /// Should return a normalized Vector2 indicating the direction
 /// in which the boid should move this step.
 /// </summary>
 /// <param name="boidAgent"></param>
 /// <returns></returns>
 public abstract Vector2 calculateGoalPosition(BoidAgent boidAgent);
示例#27
0
 private void ApplyCohesionMove(BoidAgent boid, Vector3 moveVector, float force)
 {
     boid.Rigidbody.AddForce(moveVector * (force * Time.deltaTime), ForceMode.Impulse);
 }
示例#28
0
 private void ApplyAvoidanceMove(BoidAgent boid, Vector3 direction, float force)
 {
     boid.Rigidbody.AddForce(direction * (force * Time.deltaTime), ForceMode.Impulse);
 }
示例#29
0
 private void ApplyAlignmentBehavior(BoidAgent boid)
 {
     var neighbouringBoids          = GetBoidsInRange(boid, _boidSettings.neighborsRange);
     var averageNeighboursAlignment = GetAverageAlignment(boid, neighbouringBoids);
 }
示例#30
0
 private void ApplyForwardsMotion(BoidAgent boid)
 {
     boid.Rigidbody.AddForce(boid.transform.forward * (_boidSettings.moveSpeed * Time.deltaTime), ForceMode.Impulse);
 }