private void ApplySeparationBehavior(BoidAgent boid) { var tooCloseBoids = GetBoidsInRange(boid, _boidSettings.avoidanceRange); var avoidanceMove = GetAvoidanceMove(boid.transform.position, tooCloseBoids); ApplyAvoidanceMove(boid, avoidanceMove, _boidSettings.moveSpeed); }
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); }
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); }
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); }
private Quaternion GetAverageAlignment(BoidAgent boid, Collider[] neighbouringBoids) { Quaternion averageAlignmnent = new Quaternion(); //TODO: continue scripting return(averageAlignmnent); }
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); }
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); }
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; } }
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); } }
// 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); }
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); }
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); }
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); } }
// 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); } }
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); }
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); } }
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); }
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); }
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); }
public abstract Vector3 CalculateMove(BoidAgent agent, List <Transform> context, Boid boid);
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; }
/// <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);
private void ApplyCohesionMove(BoidAgent boid, Vector3 moveVector, float force) { boid.Rigidbody.AddForce(moveVector * (force * Time.deltaTime), ForceMode.Impulse); }
private void ApplyAvoidanceMove(BoidAgent boid, Vector3 direction, float force) { boid.Rigidbody.AddForce(direction * (force * Time.deltaTime), ForceMode.Impulse); }
private void ApplyAlignmentBehavior(BoidAgent boid) { var neighbouringBoids = GetBoidsInRange(boid, _boidSettings.neighborsRange); var averageNeighboursAlignment = GetAverageAlignment(boid, neighbouringBoids); }
private void ApplyForwardsMotion(BoidAgent boid) { boid.Rigidbody.AddForce(boid.transform.forward * (_boidSettings.moveSpeed * Time.deltaTime), ForceMode.Impulse); }