예제 #1
0
        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;
            }
        }
예제 #2
0
    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
    }
예제 #3
0
    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();
 }
예제 #5
0
 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;
 }
예제 #6
0
 public void Setup()
 {
     rule = new Rules.DistanceFromBoids_Rule();
     boid = new Boid(new Vector2(), new Vector2());
     boids = new List<Interfaces.Boid_Interface>();
     boids.Add(boid);
 }
예제 #7
0
 public void Setup()
 {
     rule = new Rules.MatchVelocity_Rule();
     boid = new Boid(new Vector2(), new Vector2());
     boids = new List<Interfaces.Boid_Interface>();
     boids.Add(boid);
 }
예제 #8
0
 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);
     }
 }
예제 #10
0
 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;
 }
예제 #11
0
 void InitializePositions()
 {
     boids = new Boid[boidsNumber];
     for(int i=0;i<boidsNumber;i++)
     {
         boids[i] = new Boid(i, boidsTransform[i].position);
     }
 }
예제 #12
0
 /// <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);
 }
예제 #13
0
 /// <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);
 }
예제 #14
0
    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);
 }
예제 #16
0
파일: Simulation.cs 프로젝트: bbhsu2/boids
 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);
 }
예제 #17
0
 /// <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);
 }
예제 #20
0
        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;
        }
예제 #21
0
파일: Simulation.cs 프로젝트: bbhsu2/boids
 //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;
 }
예제 #22
0
 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;
 }
예제 #23
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;
    }
예제 #24
0
 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));
         }
     }
 }
예제 #25
0
    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());
    }
예제 #26
0
    // 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);
    }
예제 #27
0
    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);
    }
예제 #28
0
    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);
    }
예제 #29
0
    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);
    }
예제 #30
0
파일: Behaviours.cs 프로젝트: PetLid/swarm
    /**
     * 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);
    }
예제 #31
0
    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);
    }
예제 #32
0
    // 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();
    }
예제 #33
0
    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;
    }
예제 #34
0
    //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;
    }
예제 #35
0
    /// <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);
    }
예제 #36
0
        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);
        }
예제 #37
0
    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);
        }
    }
예제 #38
0
    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 );
            }
        }
    }
예제 #39
0
        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);
        }
예제 #40
0
    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);
    }
예제 #41
0
    //查找那些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);
    }
예제 #42
0
    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;
    }
예제 #43
0
    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;
    }
예제 #44
0
    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]);
                }
            }
        }
    }
예제 #45
0
 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();
     }
 }
예제 #46
0
    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);
    }
예제 #47
0
    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++;
        }
    }
예제 #48
0
    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++;
    }
예제 #49
0
파일: Simulation.cs 프로젝트: bbhsu2/boids
 //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;
 }
예제 #50
0
    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);
    }
예제 #51
0
    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);
    }
예제 #52
0
        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;
        }
예제 #53
0
    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);
    }
예제 #54
0
 // 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;
         }
     }
 }
예제 #55
0
    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);
    }
예제 #56
0
        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;
        }
예제 #57
0
 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;
     }
 }
예제 #58
0
 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;
     }
 }
예제 #59
0
파일: Boid.cs 프로젝트: homoluden/Boids
    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);
    }
예제 #60
0
 protected virtual Boid CreateBoid()
 {
     var b = new Boid(PVector2.Zero, PVector2.Zero, Boids, FInt.ZeroF, Random);
     ResetBoid(b);
     return b;
 }