override public Vector3 Calc(BoidConfig aConfig, Boid aThisBoid, List<Boid> aAllBoids) { Vector3 output = new Vector3(0f, 0f, 0f); int numInteracted = 0; foreach (Boid boid in aAllBoids) { if (boid != aThisBoid && boid.GetBoidType() == eBoidType.Normal) { Vector3 diff = (aThisBoid.transform.position - boid.transform.position); if (diff.magnitude < aConfig.DefaultInteractionRange) { output = output + boid.transform.position; numInteracted++; } } } if(numInteracted > 0) { return ((output / numInteracted) - aThisBoid.transform.position) * myWeight; } else { return output * myWeight; } }
public CollisionAvoidanceForce( Boid.Settings sts, float sepForceAtOptDistance ) { //We make an asumption that between an obstacle and a bird on the distance OptDistance should exists same //force as between two birds on the same distance optDistance = sts.OptDistance; // Maple: // restart; // f := x-> factor2*(factor1/x^2 - 1); // Mult := 2 * SpeedMultipliyer; #When collision occurs between birds each bird has a force vector and total force is twise bigger than between wall and bird. That's why we're multiplying force // F := { f(ViewRadius) = 0, f(OptDistance) = Mult * sepForceAtOptDistance }: // Res := solve( F, {factor1, factor2} ); // RealConsts := {ViewRadius = 0.5, OptDistance = 0.1, sepForceAtOptDistance = 0.05, SpeedMultipliyer = 3}; // plot( eval(f(x), eval(Res, RealConsts) ), x = 0..eval(ViewRadius, RealConsts) ); #if COLLISION_AVOIDANCE_SQUARE var ViewRadius2 = sts.ViewRadius * sts.ViewRadius; var OptDistance2 = sts.OptDistance * sts.OptDistance; factor1 = ViewRadius2; factor2 = -2 * sts.SpeedMultipliyer * sepForceAtOptDistance * OptDistance2 / ( OptDistance2 - ViewRadius2 ); #else factor1 = sts.ViewRadius; factor2 = -2 * sts.SpeedMultipliyer * sepForceAtOptDistance * sts.OptDistance / ( sts.OptDistance - sts.ViewRadius ); #endif }
public List<Boid> GetNeighbors(Boid boi) { float closestDist = float.MaxValue; Vector3 delta; float dist; neighbors.Clear(); collisionRisks.Clear(); foreach (Boid b in boids) { if (b == boi)continue; delta = b.transform.position - boi.transform.position; dist = delta.magnitude; if (dist < closestDist) { closestDist = dist; closest = b; } if (dist < BoidSpawner.S.nearDist) { neighbors.Add(b); } if (dist < BoidSpawner.S.collisionDist) { collisionRisks.Add(b); } } if (neighbors.Count == 0) { neighbors.Add(closest); } return(neighbors); }
public BoidActionCohesion(Boid leader, IList<Boid> boidList, int cohesionRadius) { _leader = leader; _boidList = boidList; _cohesionRadius = cohesionRadius; _seekAction = new BoidActionSeek(); }
Vector3 separate(Boid[] boids) { Vector3 steering = Vector3.zero; int count = 0; // For every boid in the system, check if it's too close for(int i=0;i<boids.Length;i++){ Boid other = boids[i]; if(other == this){ continue; } float d = 0; d = (other.position-position).sqrMagnitude; if(d != 0 && d < desiredSeperation){ steering += ((position-other.position).normalized)/d; count++; } } if(count > 0){ //Debug.Log(count); steering /= (float)count; } if(steering.magnitude > 0){ steering = steering.normalized*maxForce; steering -= velocity; steering = Vector3.ClampMagnitude(steering, maxForce); } return steering; }
public void Setup() { rule = new Rules.DistanceFromBoids_Rule(); boid = new Boid(new Vector2(), new Vector2()); boids = new List<Interfaces.Boid_Interface>(); boids.Add(boid); }
public void Setup() { rule = new Rules.MatchVelocity_Rule(); boid = new Boid(new Vector2(), new Vector2()); boids = new List<Interfaces.Boid_Interface>(); boids.Add(boid); }
public void Setup() { rule = new Rules.CentreOfFlock_Rule(); boid = new Boid(new Vector2(), new Vector2()); boids = new List<Interfaces.Boid_Interface>(); boids.Add(boid); }
public void UnRegister(Boid b) { foreach (KeyValuePair<string, List<Boid>> item in Squads) { UnRegister(b, item.Key); } }
public SeparationForce( Boid.Settings sts ) { //We have to compensate cohesion force which in the OptDistance point //equals OptDistance / 2 //solve( {optFactor / OptDistance = OptDistance / 2}, {optFactor} ); optFactor = sts.OptDistance * sts.OptDistance / 2; }
void InitializePositions() { boids = new Boid[boidsNumber]; for(int i=0;i<boidsNumber;i++) { boids[i] = new Boid(i, boidsTransform[i].position); } }
/// <summary> /// Creates a new Dance process /// </summary> /// <param name="boid">The boid this process will control</param> /// <param name="toSatisfy">The need this process will satisfy</param> public DanceProcess(Boid boid, Need toSatisfy) { owner = boid; ownerDesire = toSatisfy; ProcessList.Add(navigateToStage); ProcessList.Add(continueWalkToStage); ProcessList.Add(reachStage); }
/// <summary> /// Creates new Bar Process /// </summary> /// <param name="boid">The boid this process will control</param> /// <param name="toSatisfy">The need this process will satisfy</param> public BarProcess(Boid boid, Need toSatisfy) { owner = boid; ownerDesire = toSatisfy; ProcessList.Add(navigateToBar); ProcessList.Add(continueWalkToBar); ProcessList.Add(reachBar); ProcessList.Add(drink); }
void Awake() { boidComponent = transform.GetComponent<Boid>(); pc = transform.GetComponent<PlayerController>(); strength = pc.attackStrengths[0]; attackRadius = pc.attackRadius; attackCooldown = pc.attackCooldown; }
public BoidCombinedActionFCAS(Boid boid, IList<Boid> boidList, IList<Boid> predatorBoidsList, int cohesionRadius) { _boidList = boidList; _randomPredatorBoidsList = predatorBoidsList; _fleeAction = new BoidActionFlee(); _cohesionAction = new BoidActionCohesion(boid, boidList, cohesionRadius); _aligmentAction = new BoidActionAligment(boid, boidList); _separateAction = new BoidActionSeparate(boid, boidList); }
public void AddBoid() { var x = rnd.Next(Game1.ScreenBounds.Width / 2, Game1.ScreenBounds.Width / 2); var y = rnd.Next(Game1.ScreenBounds.Height / 2, Game1.ScreenBounds.Height / 2); //var x = rnd.Next(Game1.ScreenBounds.Width / 2 - 100, Game1.ScreenBounds.Width / 2 + 200); //var y = rnd.Next(Game1.ScreenBounds.Height / 2 - 100, Game1.ScreenBounds.Height / 2 + 200); Boid boid = new Boid(this.boidTexture, rnd.NextDouble(), x, y); Boids.Add(boid); }
/// <summary> /// Creates a new Toilet process /// </summary> /// <param name="boid">The boid this process will control</param> /// <param name="toSatisfy">The need this process will satisfy</param> public ToiletProcess(Boid boid, Need toSatisfy) { owner = boid; ownerDesire = toSatisfy; ProcessList.Add(navigateToToilet); ProcessList.Add(continueWalkToToilet); ProcessList.Add(reachToilet); ProcessList.Add(pee); }
public void UnRegister(Boid b, string squad) { Squads[squad].Remove(b); AllBoids.Remove(b); if (Squads[squad].Count == 0) { Squads[squad] = null; } }
public void Register(Boid b, string squad) { List<Boid> l; if (!Squads.TryGetValue(squad, out l)) { Squads[squad] = new List<Boid>(); } AllBoids.Add(b); Squads[squad].Add(b); }
protected virtual void ResetBoid(Boid b) { var direction = MathHelper.Lerp(0, MathHelper.TwoPi, (float)Random.NextDouble()); var speed = Random.NextDouble() * MaxVelocity.ToDouble(); var v = PVector2.Zero; v.X = new FInt((Math.Cos(direction) * speed)); v.Y = new FInt((Math.Sin(direction) * speed)); var p = new PVector2((FInt)Random.Next(-400, 400), (FInt)Random.Next(-400, 400)); b.Position = p; b.VelocityPerTick = v; b.Dead = false; }
//Fly to the center of mass of other boids public Vector2 Rule1(Boid boid, bool isSimple) { Vector2 pcj = Vector2.Zero; int neighborCount = 0; foreach (Boid b in Boids) { if (boid != b && (b.Position-boid.Position).Length() < 700) { pcj += b.Position; neighborCount++; } } pcj /= neighborCount + 1; //(Boids.Count - 1); return (pcj - boid.Position) * 0.01f; }
public void run(Boid[] boids, Vector3 target) { Vector3 seeking = seek(target); Vector3 sep = separate(boids); // weight forces seeking *= 1f; sep *= 1.2f; acceleration += sep; acceleration += seeking; velocity += acceleration; velocity = Vector3.ClampMagnitude(velocity, maxSpeed); position += velocity; acceleration *= 0; }
Vector3 MoveToCenter(Boid b) { //Cohésion var perceivedCenter = new Vector3(0,0,0); ; for(int i=0;i<boidsNumber;i++) { if(b.id != boids[i].id) perceivedCenter += boids[i].position; } perceivedCenter /= (boids.Length - 1); return (perceivedCenter - b.position)/100; }
public override void Update() { // Somebody elase eaten the food? if (food == null) { owner.SwitchState(new IdleState(owner)); } else { Boid boid = owner.GetComponent <Boid>(); boid.seekTargetPosition = food.transform.position; if (Vector3.Distance(owner.transform.position, food.transform.position) < 1.0f) { EatFood(); owner.SwitchState(new IdleState(owner)); } } }
void InitializePoolAndComputeShader() { _boidsTab = new Boid[nbBoid]; GameObject boidContainer = Instantiate(_boidContainer); for (int i = 0; i < _boidsTab.Length; i++) { Boid curBoid = Instantiate(_boidPrefab); curBoid.transform.position = new Vector3(0, -2000, 0); curBoid.transform.SetParent(boidContainer.transform); _boidsTab[i] = curBoid; } boidData = new BoidData[_boidsTab.Length]; boidBuffer = new ComputeBuffer(_boidsTab.Length, BoidData.Size); m_boidCor = StartCoroutine(corBoid()); }
// slow down when close to target public static Vector3 CalculateArrive(Boid boid, Transform target, float slowingDistance, float maxSpeed) { Vector3 desired = Vector3.zero; var offset = target.position - boid.Position; var distance = offset.magnitude; var rampedSpeed = maxSpeed * (distance / slowingDistance); var clippedSpeed = Math.Min(rampedSpeed, maxSpeed); if (distance > 0) { desired = (clippedSpeed / distance) * offset; } desired -= boid.Velocity; return(desired); }
public Vector2 CalculateAlignment(Boid boid, List <Transform> context) { if (context.Count == 0) { return(boid.transform.up); } Vector2 aligmentMove = Vector2.zero; foreach (Transform item in context) { aligmentMove += (Vector2)item.transform.up; } aligmentMove /= context.Count; return(aligmentMove); }
public static Vector3 getAffect(Boid boid, List <Boid> otherBoids) { Vector3 c = Vector3.zero; foreach (Boid otherBoid in otherBoids) { if (otherBoid == boid) { continue; } if ((otherBoid.transform.position - boid.transform.position).magnitude < BoidConfig.Instance.separationRadius) { c = c - (otherBoid.transform.position - boid.transform.position); } } return(c); }
public override NodeResult Execute() { Boid target = ((GameObject)tree.GetValue(TargetKey)).GetComponent <Boid>(); if (target != null) { LineRenderer lr = tree.gameObject.GetComponent <LineRenderer>(); Vector3[] position = new Vector3[2]; position[0] = tree.transform.position; position[1] = target.transform.position; lr.SetPositions(position); return(NodeResult.SUCCESS); } return(NodeResult.FAILURE); }
/** * Generates a velocity pointing away from an obstacle * based on a boid's position. * * @param Boid b, the boid instance * @return Vector2, the generated velocity vector */ public static Vector2 Rule_AvoidObstacle(Boid b, Vector3 obstaclePos) { // Vector from boid to obstacle Vector2 boidToObstacle = b._pos - (Vector2)obstaclePos; // Calculate distance float distance = boidToObstacle.magnitude; // If distance is smaller than diamater of obstacle sprite if (distance < Globals.obstacleRadius * 2) { // Change velocity based off of distance, quadratic fall-off return(boidToObstacle / ((distance * distance * 100) + SAFEGUARD)); } // If too far from obstacle return a zero velocity return(Vector2.zero); }
public static Vector2 GetSeprationSteer(Boid unit, List <Boid> neighbors, out Boid collider) { collider = null; Vector2 separationDir = Vector2.zero; foreach (var neighbor in neighbors) { Vector2 offset = unit.Position - neighbor.Position; float radiusSum = unit.Radius + neighbor.HardRadius; if (offset.sqrMagnitude < radiusSum * radiusSum) { collider = neighbor; return(GetAvoidSteer(unit, neighbor)); } separationDir += offset / offset.sqrMagnitude; } return(separationDir.normalized); }
// Start is called before the first frame update void Start() { //Assign scripts of this fighter. seek = GetComponent <Seek>(); arrive = GetComponent <Arrive>(); attack = GetComponent <Attack>(); boid = GetComponent <Boid>(); //Get material from base. foreach (Renderer r in GetComponentsInChildren <Renderer>()) { Material m_Material = Base.GetComponent <Renderer>().material; r.material = m_Material; } //Pick a target. ChooseTarget(); }
void CreateFollower(Vector3 offset, Boid leader) { GameObject follower = GameObject.Instantiate <GameObject> (prefab); follower.transform.position = leader.transform.TransformPoint(offset); follower.transform.parent = this.transform; follower.transform.rotation = this.transform.rotation; OffsetPursue op = follower.AddComponent <OffsetPursue> (); op.leader = leader; Seek seek = follower.AddComponent <Seek> (); seek.enabled = !seek.enabled; Boid b = follower.GetComponent <Boid> (); b.maxSpeed = 6.5f; }
//Function to create followers void CreateFollower(Vector3 offset, Boid leader) { GameObject follower = GameObject.Instantiate <GameObject> (prefab); follower.transform.position = leader.transform.TransformPoint(offset); follower.transform.parent = this.transform; follower.transform.rotation = this.transform.rotation; //add steering behaviours Wander w = follower.AddComponent <Wander>(); Seek seek = follower.AddComponent <Seek> (); seek.enabled = !seek.enabled; ObstacleAvoidance obavd = follower.AddComponent <ObstacleAvoidance> (); Boid b = follower.GetComponent <Boid> (); b.maxSpeed = 2; }
/// <summary> /// Is boid still in flock /// </summary> /// <param name="tBoid"> Boic </param> /// <returns> Boid in flock or not </returns> public bool Contain(Boid tBoid) { Vector3 v3LocalBoidPos = transform.worldToLocalMatrix * tBoid.transform.position; if (v3LocalBoidPos.x > FlockWidth / 2 || v3LocalBoidPos.x < -FlockWidth / 2) { return(false); } if (v3LocalBoidPos.y > FlockHeight / 2 || v3LocalBoidPos.y < -FlockHeight / 2) { return(false); } if (v3LocalBoidPos.z > FlockDepth / 2 || v3LocalBoidPos.z < -FlockDepth / 2) { return(false); } return(true); }
public override Vector2 CalculateMove(Boid boid) { Assert.IsTrue(boid != null); Vector2 compositeMove = Vector2.zero; foreach (var pair in m_pairs) { BoidBehaviour behaviour = pair.BoidBehaviour; float weight = pair.Weight; compositeMove += (behaviour.CalculateMove(boid).normalized *weight); } compositeMove /= m_pairs.Count; compositeMove.Normalize(); return(compositeMove); }
public void InstantiateBoid() { GameObject go = Instantiate(boidPrefab); Boid b = go.GetComponent <Boid>(); b.transform.SetParent(boidAnchor); boids.Add(b); if (boids.Count < numBoids) { //InstantiateBoid() is initially called once by Awake(), and then //InstantiateBoid() uses the Invoke() function to call itself again //until the number of Boids instantiated is equal to numBoids.The two //arguments that Invoke takes are the name of the method to be called(as a //string: "InstantiateBoid") and the amount of time to wait before //calling it(spawnDelay, or 0.1 seconds). Invoke("InstantiateBoid", spawnDelay); } }
void GetFlock() { Boid[] boids = FindObjectsOfType(typeof(Boid)) as Boid[]; // add all boids except for self for (int i = 0; i < boids.Length; i++) { int id1 = boids[i].GetInstanceID(); Boid boid = gameObject.GetComponent(typeof(Boid)) as Boid; int id2 = boid.GetInstanceID(); if (id1 != id2) { flock.Add(boids[i]); //print ( "me=" + gameObject.name + " adding=" + boids[i].name ); } } }
public override Vector3 CalculateMove(Boid boid, List <Transform> neighbours, BoidLeader leader) { var average = new Vector3(0, 0, 0); //If no neighbours, return no adjustment if (neighbours.Count == 0) { return(average); } //Calculate the average position of neighbours average = neighbours.Aggregate(average, (current, neighbour) => current + neighbour.position); //Reduce the average down to the average between all neighbours, removing player position and reducing down to 1% average /= neighbours.Count; average = (average - boid.transform.position); return(average); }
Boid GetClosestEnemy(List <Boid> enemies) { Boid bestTarget = null; float closestDistanceSqr = Mathf.Infinity; foreach (Boid potentialTarget in enemies) { Vector2 directionToTarget = potentialTarget.position - position; float dSqrToTarget = directionToTarget.sqrMagnitude; if (dSqrToTarget < closestDistanceSqr) { closestDistanceSqr = dSqrToTarget; bestTarget = potentialTarget; } } return(bestTarget); }
//查找那些Boid距离当前Boid距离足够近,可以被当作附近对象 public List <Boid> GetNeighbors(Boid boi) { float closesDist = float.MaxValue; //最小间距,MaxValue 为浮点数的最大值 Vector3 delta; //当前 boid 与其他某个 boid 的三维间距 float dist; //三位间距转换为的 实数间距 neighbors.Clear(); //清理上次表的数据 collisionRisks.Clear(); //清理上次表的数据 //遍历目前所有的 boid,依据设定的范围值筛选出 附近的boid 与 最近的boid 于各自表中 foreach (Boid b in boids) { if (b == boi) //跳过自身 { continue; } delta = b.transform.position - boi.transform.position; //遍历到的 b 与当前持有的 boi(都为boid) 的三维间距 dist = delta.magnitude; //实数间距 if (dist < closesDist) { closesDist = dist; //更新最小间距 closest = b; //更新最近的 boid 为 b } if (dist < groupAI.nearDist) //处在附近的 boid 范围 { neighbors.Add(b); } if (dist < groupAI.collisionDist) //处在最近的 boid 范围(有碰撞风险) { collisionRisks.Add(b); } } if (neighbors.Count == 0) //若没有其他满足邻近范围的boid,则将自身boid纳入附近的boid表中 { neighbors.Add(closest); } return(neighbors); }
private void StartSimulation() { for (int i = 0; i < numberOfBoids; i++) { Vector3 pos = Vector3.zero; if (randomStartPositions) { pos = new Vector3( Random.Range(-maxDistance, maxDistance), Random.Range(-maxDistance, maxDistance), Random.Range(-maxDistance, maxDistance) ); } Boid boid = GetBoid(pos); boid.InitialiseBoid( this, Random.Range(minMass, maxMass), visionSize ); boid.ShowMesh(showMesh); boid.ShowTrail(showTrail); boids.Add(boid); } //for ( int i = 0; i < numberOfBoids; i++ ) //{ // boids[ i ].SetNeighbours( boids ); //} camControl.SetTargetBoid(boids[Random.Range(0, numberOfBoids)]); if (audioMode) { timeSinceLastCameraChange = 0f; soundTrack.Play(); } simulationHasStarted = true; }
private void CalculateAverages() { Vector3 sumForward = Vector3.zero; Vector3 sumPosition = Vector3.zero; int count = 0; foreach (var Boid in Boids) { count++; sumPosition += Boid.transform.position; sumForward += Boid.GetComponent <Rigidbody>().velocity; } sumForward /= count; sumPosition /= count; AveragePosition = sumPosition; AverageForward = sumForward; }
private void PerformNeighbourSearch() { float neighbourRadSqr = m_neighbourRadius * m_neighbourRadius; for (int i = 0; i < m_numBoids; ++i) { Boid boid = m_boids[i]; Vector3 boidPos = boid.transform.position; for (int j = i + 1; j < m_numBoids; ++j) { float distanceSquared = (m_boids[j].transform.position - boidPos).sqrMagnitude; if (distanceSquared <= neighbourRadSqr) { m_boids[i].AddNeighbour(m_boids[j]); m_boids[j].AddNeighbour(m_boids[i]); } } } }
public void add(Boid boid) { if (boids.Count > boid.boidManager.maximumClusterSize) { return; } boids.Add(boid); boid.cluster = this; if (boids.Count == 1) { clusterDirection = boid.transform.right; parentBoid = boid; } else { updateDirection(boid); updateCenterOfMass(); } }
private List <Boid> GetNeighbors(Boid boid) { var closestDist = float.MaxValue; var delta = Vector3.zero; var dist = 0f; _neighbors.Clear(); _collisionRisks.Clear(); foreach (var b in Boids) { if (b == boid) { continue; } delta = b.transform.position - boid.transform.position; dist = delta.magnitude; if (dist < closestDist) { closestDist = dist; _closest = b; } if (dist < BoidSpawner.Instance.nearDist) { _neighbors.Add(b); } if (dist < BoidSpawner.Instance.collisionDist) { _collisionRisks.Add(b); } } if (_neighbors.Count == 0) { _neighbors.Add(_closest); } return(_neighbors); }
public void infectHuman(uint humanID, uint zombieID) { if (!isBoidGoingToBeRemoved(humanID)) { Boid human = getBoid(humanID); Boid zombie = getBoid(zombieID); float humanFuel = human.getFuel(); float zombieFuel = zombie.getFuel(); float fuel = humanFuel; Boid newZombie = new Zombie(new GeneticCode(zombie.getGeneticCode(), 0.05f)); newZombie.setPosition(zombie.getPosition()); newZombie.setFuel(fuel); zombie.setFuel(zombie.getFuel() + fuel); killHuman(humanID); boidsToAdd.Add(newZombie); zombiesAlive++; } }
private void addBoid(Boid toAdd) { if (toAdd.getFaction() == "Child" || toAdd.getFaction() == "Male" || toAdd.getFaction() == "Female" || toAdd.getFaction() == "PregnantFemale") { toAdd.setObj(Instantiate(HumanPrefab, toAdd.getPosition(), Quaternion.identity)); } else if (toAdd.getFaction() == "Zombie") { toAdd.setObj(Instantiate(ZombiePrefab, toAdd.getPosition(), Quaternion.identity)); } else { toAdd.setObj(Instantiate(FoodPrefab, toAdd.getPosition(), Quaternion.identity)); } boids.Add(toAdd); boidCount++; }
//Keep a small distance away from other objects public Vector2 Rule2(Boid boid) { Vector2 vec = Vector2.Zero; int neighborCount = 0; foreach (Boid b in Boids) { if (b != boid) { var distance = (boid.Position - b.Position).Length(); if (0 < distance && distance < DESIRED_SEPARATION) { var deltaVector = boid.Position - b.Position; deltaVector.Normalize(); deltaVector /= distance; vec += deltaVector; neighborCount++; } } } Vector2 averageSteeringVector = (neighborCount > 0) ? vec / neighborCount : Vector2.Zero; return averageSteeringVector; }
public override Vector2 GetForce2(Boid thisBoid, List <Boid> localBoids) { if (localBoids.Count == 0) { return(Vector2.zero); } Vector2 avgPos = Vector2.zero; foreach (Boid b in localBoids) { avgPos += b.rb.position; } avgPos = avgPos / localBoids.Count; Vector2 displacement = avgPos - thisBoid.rb.position; float forceMagnitude = displacement.magnitude / thisBoid.interactionRadius; Vector2 force = forceMagnitude * strength * displacement.normalized; return(force); }
public Vector3 Flock(Boid boid, Vector3 boidPosition, Vector3 boidDirection) { flockDirection = Vector3.zero; flockCenter = Vector3.zero; targetDirection = Vector3.zero; separation = Vector3.zero; for (int i = 0; i < flockList.Count; ++i) { Boid neighbor = flockList[i]; //Check only against neighbors if (neighbor != boid) { //Aggregate the direction of all the boids flockDirection += neighbor.Direction; //Aggregate the position of all the boids flockCenter += neighbor.transform.localPosition; //Aggregate the delta to all the boids separation += neighbor.transform.localPosition - boidPosition; separation *= -1; } } //Alignment. The average direction of all boids flockDirection /= flockSize; flockDirection = flockDirection.normalized * alignmentWeight; //Cohesion. The centroid of the flock flockCenter /= flockSize; flockCenter = flockCenter.normalized * cohesionWeight; //Separation. separation /= flockSize; separation = separation.normalized * separationWeight; //Direction vector to the target of the flock. targetDirection = target.localPosition - boidPosition; targetDirection = targetDirection * followWeight; return(flockDirection + flockCenter + separation + targetDirection); }
override public Vector3 Calc(BoidConfig aConfig, Boid aThisBoid, List<Boid> aAllBoids) { Vector3 output = new Vector3(0.0f, 0.0f, 0.0f); foreach (Boid boid in aAllBoids) { if(boid != aThisBoid) { Vector3 diff = (boid.transform.position - aThisBoid.transform.position); if (diff.magnitude < boid.GetRepulsionRange()) { // output = (((output - diff)) / Mathf.Min(diff.magnitude, 1.0f)) * boid.GetRepulsionFactor(); output = output - diff * boid.GetRepulsionFactor() ; } } } return output * myWeight; }
List <Transform> GetNearbyObjects(Boid boid) { List <Transform> context = new List <Transform> (); Collider2D[] contextColliders = Physics2D.OverlapCircleAll(boid.transform.position, neighbourhoodRadius); //Go through all the contextColliders foreach (Collider2D col in contextColliders) { //As long as it's not this boid if (col != boid.BoidCollider) { //Add the transform to the context context.Add(col.transform); } } return(context); }
// Update is called once per frame void Update( ) { for (int i = _boids.Count - 1; i >= 0; --i) { Boid b = _boids[i]; Vector3 pos = b.transform.position; //if the boid is outside of the flockingArea, remove it from theh simulation. if ((_width > 0 && (pos.x <= _posX - _width / 2 || pos.x >= _posX + _width / 2)) || (_height > 0 && (pos.y <= _posY - _height / 2 || pos.y >= _posY + _height / 2)) || (_depth > 0 && (pos.z <= _posZ - _depth / 2 || pos.z >= _posZ + _depth / 2))) { //wait until the tail is at the boids current location (so it is not abruptly deleted). GameObject.Destroy(b.gameObject, 0.5f); //no longer include this boid in any calculation by removing it from the boids collection. _boids.RemoveAt(i); b = null; } } }
public override Vector2 GetForce2(Boid thisBoid, List <Boid> localBoids) { if (localBoids.Count == 0) { return(Vector2.zero); } Vector2 averageDir = Vector2.zero; foreach (Boid b in localBoids) { averageDir += b.rb.velocity.normalized; } averageDir = averageDir / localBoids.Count; float angle = Vector2.Angle(averageDir, thisBoid.rb.velocity); float forceMagnitude = angle / 180; Vector2 force = strength * forceMagnitude * averageDir.normalized; return(force); }
override public Vector3 Calc(BoidConfig aConfig, Boid aThisBoid, List<Boid> aAllBoids) { Vector3 output = new Vector3(0.0f, 0.0f, 0.0f); if (aThisBoid.transform.position.x < aConfig.SpawnBoundsStart.x + 1.0f) output.x = 1.0f; else if (aThisBoid.transform.position.x > aConfig.SpawnBoundsEnd.x - 1.0f) output.x = -1.0f; if (aThisBoid.transform.position.y < aConfig.SpawnBoundsStart.y + 1.0f) output.y = 1.0f; else if (aThisBoid.transform.position.y > aConfig.SpawnBoundsEnd.y - 1.0f) output.y = -1.0f; if (aThisBoid.transform.position.z < aConfig.SpawnBoundsStart.z + 1.0f) output.z = 1.0f; else if (aThisBoid.transform.position.z > aConfig.SpawnBoundsEnd.z - 1.0f) output.z = -1.0f; return output * myWeight; }
private Vector3 cohere(Boid boid) { Vector3 centerOfMass = Vector3.zero; int count = 0; for (int i = 0; i < numberOfBoids; i++) { float distance = Vector3.Distance(boids[i].transform.localPosition, boid.transform.localPosition); if (distance > 0 && distance < boid.neighborRadius) { centerOfMass += boids[i].transform.localPosition; count++; } } if (count > 0) { return ((centerOfMass / (numberOfBoids - 1)) - boid.transform.localPosition).normalized; } else { return Vector3.zero; } }
private Vector3 align(Boid boid) { Vector3 velocity = Vector3.zero; int count = 0; for (int i = 0; i < numberOfBoids; i++) { float distance = Vector3.Distance(boids[i].transform.localPosition, boid.transform.localPosition); if (distance > 0 && distance < boid.neighborRadius) { velocity += boids[i].thisRigidbody.velocity; count++; } } if (count > 0) { return (velocity / (numberOfBoids - 1)).normalized; } else { return Vector3.zero; } }
void CalculateVelocity() { boids = Physics.OverlapSphere(tr.position, cohesionRadius, boidsLayer.value); if (boids.Length < 2) return; velocity = Vector3.zero; cohesion = Vector3.zero; separation = Vector3.zero; separationCount = 0; alignment = Vector3.zero; for (i = 0; i < boids.Length && i < maxBoids; i++) { b = boids[i].GetComponent<Boid>(); cohesion += b.tr.position; alignment += b.velocity; vector = tr.position - b.tr.position; if (vector.sqrMagnitude > 0 && vector.sqrMagnitude < separationDistance * separationDistance) { separation += vector / vector.sqrMagnitude; separationCount++; } } cohesion = cohesion / (boids.Length > maxBoids ? maxBoids : boids.Length); cohesion = Vector3.ClampMagnitude(cohesion - tr.position, maxSpeed); cohesion *= cohesionCoefficient; if (separationCount > 0) { separation = separation / separationCount; separation = Vector3.ClampMagnitude(separation, maxSpeed); separation *= separationCoefficient; } alignment = alignment / (boids.Length > maxBoids ? maxBoids : boids.Length); alignment = Vector3.ClampMagnitude(alignment, maxSpeed); alignment *= alignmentCoefficient; velocity = Vector3.ClampMagnitude(cohesion + separation + alignment, maxSpeed); }
protected virtual Boid CreateBoid() { var b = new Boid(PVector2.Zero, PVector2.Zero, Boids, FInt.ZeroF, Random); ResetBoid(b); return b; }