예제 #1
0
    public void Setup()
    {
        squareMaxSpeed        = maxSpeed * maxSpeed;
        squareNeightborRadius = neighborRadius * neighborRadius;
        squareAvoidanceRadius = squareNeightborRadius * avoidanceRadiusMultiplier * avoidanceRadiusMultiplier;

        //instantiate flock
        for (int i = 0; i < startingCount; i++)
        {
            FlockAgent newAgent = Instantiate(
                agentPrefab,
                Random.insideUnitSphere * startingCount * DENSITY,
                Quaternion.Euler(Vector3.forward * Random.Range(0f, 360f)),
                transform);

            newAgent.name = "Ghost " + i;
            agents.Add(newAgent);
        }
    }
예제 #2
0
    public override Vector3 CalculateMove(FlockAgent agent, List <Transform> subFlock, Flock flock)
    {
        // if no member, maintain current
        if (subFlock.Count == 0)
        {
            return(agent.transform.forward);
        }
        Vector3          alignmentMove    = Vector3.zero;
        List <Transform> filteredSubFlock = (filter == null) ? subFlock : filter.GetFilteredFlock(agent, subFlock);

        // get average of sub flock forward as alignment
        foreach (Transform item in filteredSubFlock)
        {
            alignmentMove += item.transform.forward;
            //alignmentMove += item.forward;
        }
        alignmentMove /= filteredSubFlock.Count;
        return(alignmentMove);
    }
예제 #3
0
    public override Vector2 CalculateMove(FlockAgent agent, List <Transform> context, Flock flock)
    {
        if (context.Count == 0)
        {
            return(agent.transform.up);
        }

        Vector2          alignmentMove   = Vector2.zero;
        List <Transform> filteredContext = (filter == null) ? context : filter.Filter(agent, context);

        foreach (Transform item in filteredContext)
        {
            alignmentMove += (Vector2)item.transform.up;
        }

        alignmentMove /= context.Count;

        return(alignmentMove);
    }
    public override Vector3 CalculateMove(FlockAgent agent, List <Transform> context, Flock flock)
    {
        // If no neighbors, maintain current alignment
        if (context.Count == 0)
        {
            return(agent.transform.forward);
        }

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

        foreach (Transform item in context)
        {
            alignmentMove += item.transform.forward;
        }
        alignmentMove /= context.Count;

        return(alignmentMove);
    }
예제 #5
0
    // Start is called before the first frame update
    void Start()
    {
        squareMaxSpeed     = maxSpeed * maxSpeed;
        squareNeighborRad  = neighborRad * neighborRad;
        squareAvoidanceRad = squareNeighborRad * avoidanceRadMultiplier * avoidanceRadMultiplier;

        for (int i = 0; i < startingCount; i++)
        {
            FlockAgent newAgent = Instantiate(
                agentPrefab,
                (Random.insideUnitSphere * startingCount * AgentDensity * spawnSize) + transform.position,
                Quaternion.Euler(Vector3.up * Random.Range(0f, 360f)),
                transform
                );
            newAgent.name = "Agent " + i;
            newAgent.Initialize(this);
            agents.Add(newAgent);
        }
    }
예제 #6
0
        public override Vector2 CalculateMove(FlockAgent agent, List <Transform> context, Flock flock)
        {
            // if have no neighbor, miantain current alingment
            if (context.Count == 0)
            {
                return(agent.transform.up);
            }

            // add all points together and average
            Vector2 alignmentMove = Vector2.zero;

            foreach (Transform item in context)
            {
                alignmentMove += (Vector2)item.transform.up;
            }
            alignmentMove /= context.Count;

            return(alignmentMove);
        }
예제 #7
0
    private Vector2 FollowPath(FlockAgent agent)
    {
        if (path == null)
        {
            return(Vector2.zero);
        }

        if (InRadius(agent)) //if inside the radius of a path, then go to the next one.
        {
            currentWaypoint++;
            if (currentWaypoint >= path.waypoints.Count)
            {
                currentWaypoint = 0;
            }
            return(Vector2.zero);
        }

        return(waypointDirection);
    }
    public float colorLerpDivider = 6f;       //The multiplier/divider used to calculate the Lerp rate for the gradient color effect
    #endregion

    #region Default
    void Start()
    {
        #region Square Setups
        //set up the squared values to be correct
        squareMaxSpeed        = maxSpeed * maxSpeed;                                                           //max speed
        squareNeighbourRadius = neighbourRadius * neighbourRadius;                                             //neighbourRadius
        squareAvoidanceRadius = squareNeighbourRadius * avoidanceRadiusMultiplier * avoidanceRadiusMultiplier; //avoidance radius (kinda). 0.5 times bigger than neighbourRadius
        #endregion

        #region Setup each agent
        for (int i = 0; i < startingCount; i++)                                                                                                                                            //For each agent in our flock
        {
            FlockAgent newAgent = Instantiate(agentPrefab, Random.insideUnitCircle * startingCount * AgentDensity, Quaternion.Euler(Vector3.forward * Random.Range(0f, 360f)), transform); //Create an agent prefab object within the scene at the correct position
            newAgent.Initialize(this);                                                                                                                                                     //Set up the agent with the FlockAgent script
            newAgent.name = "Agent " + 1;                                                                                                                                                  //Name it to its numarical correspondance
            agents.Add(newAgent);                                                                                                                                                          //Add a new agent to the list of agents for use later
        }
        #endregion
    }
예제 #9
0
    public override Vector3 CalculateMove(FlockAgent agent, List <Transform> context, FlockManager flockManager)
    {
        //no neighbors means maintain heading
        if (context.Count == 0)
        {
            return(agent.transform.forward);
        }

        //add all points together and average
        Vector3 alignmentMove = Vector3.zero;

        foreach (Transform item in context)
        {
            alignmentMove += item.transform.forward;
        }
        alignmentMove /= context.Count;

        return(alignmentMove);
    }
예제 #10
0
    public override List <Transform> Filter(FlockAgent agent, List <Transform> original, Dictionary <string, FlockAgent> agents)
    {
        List <Transform> filtered = new List <Transform>();

        foreach (Transform item in original)
        {
            FlockAgent itemAgent = agents[item.name];
            if (itemAgent == null)
            {
                Debug.LogError("This sholud not happen.");
            }

            if (itemAgent.Flock == agent.Flock)
            {
                filtered.Add(item);
            }
        }
        return(filtered);
    }
예제 #11
0
    void Start()
    {
        squareMaxSpeed        = maxSpeed * maxSpeed;
        squareNeighborRadius  = neighborRadius * neighborRadius;
        squareAvoidanceRadius = squareNeighborRadius * avoidanceRadiusMultiplier * avoidanceRadiusMultiplier;

        for (int i = 0; i < startingCount; i++)
        {
            FlockAgent newAgent = Instantiate(agentPrefab);
            newAgent.transform.position = Random.insideUnitSphere * startingCount * AgentDensity;
            newAgent.transform.rotation = Random.rotation;
            newAgent.transform.SetParent(transform, false);
            Debug.Log(newAgent.transform.forward);

            newAgent.name = string.Format("Agent {0}", i);
            newAgent.Initialize(this);
            agents.Add(newAgent);
        }
    }
예제 #12
0
    public override Vector3 CalculateMove(FlockAgent agent, List <Transform> context, Flock flock)
    {
        // if no neighbours, maintain current alingment
        if (context.Count == 0)              //finds middle point between neighbours and tries to move there
        {
            return(agent.transform.forward); //use .forward for 3d
        }
        //add all points together and average them
        Vector3          AlignmentMove   = Vector3.zero;
        List <Transform> filteredContext = (filter == null) ? context : filter.Filter(agent, context);

        foreach (Transform item in filteredContext)
        {
            AlignmentMove += (Vector3)item.transform.forward;
        }
        AlignmentMove /= context.Count; //maybe change back to context

        return(AlignmentMove);
    }
예제 #13
0
    public override Vector2 CalculateMove(FlockAgent agent, List <FlockAgent> context, Flock flock)
    {
        // no neighbor, maintain current rotaiton
        if (context.Count == 0)
        {
            return(agent.direction);
        }

        //average point
        Vector2 aligenementMove = Vector2.zero;

        foreach (FlockAgent item in context)
        {
            aligenementMove += (Vector2)item.direction;
        }
        aligenementMove /= context.Count;

        return(aligenementMove);
    }
예제 #14
0
    public override Vector2 CalculateMove(FlockAgent agent, List <Transform> context, Flock flock)
    {
        if (context.Count == 0)
        {
            return(Vector2.zero);
        }
        Vector2          cohesionMove    = Vector2.zero;
        List <Transform> filteredContext = (filter == null) ? context : filter.Filter(agent, context);

        foreach (Transform item in filteredContext)
        {
            cohesionMove += (Vector2)item.position;
        }
        cohesionMove /= context.Count;
        cohesionMove -= (Vector2)agent.transform.position;
        cohesionMove  = Vector2.SmoothDamp(agent.transform.up, cohesionMove, ref currentVelocity, agentSmoothTime);

        return(cohesionMove);
    }
    public override Vector2 CalculateMove(FlockAgent agent, List <Transform> context, Flock flock)
    {
        if (context.Count == 0)
        {
            return(Vector2.zero);
        }
        else
        {
            Vector2 cohesionMove = Vector2.zero;
            foreach (Transform item in context)
            {
                cohesionMove += (Vector2)item.position;
            }
            cohesionMove /= context.Count;
            cohesionMove -= (Vector2)agent.transform.position;

            return(cohesionMove);
        }
    }
예제 #16
0
    public Vector2 Seek(FlockAgent agent, Vector3 startingPos, Vector3 targetPos)
    {
        /* Seek behavior is a smoothed method for facing a target */

        // Get the target vector. Target = target pos - agent pos
        Vector2 targetVector = new Vector2(
            targetPos.x - startingPos.x,
            targetPos.y - startingPos.y
            ).normalized *agent.maxSpeed;

        targetVector = Vector2.SmoothDamp(
            agent.transform.up,
            targetVector,
            ref agent.currentVelocity,
            agent.agentSmoothTime
            );

        return(targetVector);
    }
예제 #17
0
    public override Vector2 CalculateMove(FlockAgent agent, List <Transform> context, Flock flock)
    {
        if (agent.isEvade)                                                     //if agent is trying to evade
        {
            Vector2 centerOffset = center - (Vector2)agent.transform.position; //the direction to center, mag would be the distance to center.
            float   t            = centerOffset.magnitude / radius;            //if t=0, at center. if t=1, at circumference. if t>1, outside circle
            //Could use sqrMagnitude if you precalculate radius squared, would still be accurate that t<0 = inside and t>0 = outside circle

            if (t < 0.9f)             //if within 90% of radius // this would NOT be an accurate 90% if we were to use sqrMag above.
            {
                return(Vector2.zero); //don't bother changing anything
            }

            //otherwise if close to or beyond radius

            return(centerOffset * t * t); //return to center at a quadratically(looks more swoopish) more intense rate the further away agent is.
        }
        return(Vector2.zero);             //don't bother changing anything
    }
예제 #18
0
    // Start is called before the first frame update
    void Start()
    {
        squareMaxSpeed        = maxSpeed * maxSpeed;
        squareNeighborRadius  = neighborRadius * neighborRadius;
        squareAvoidanceRadius = squareNeighborRadius * avoidanceRadiusMultiplier * avoidanceRadiusMultiplier;

        for (int i = 0; i < startingCount; i++)
        {
            FlockAgent newAgent = Instantiate(
                agentPrefab,
                Random.insideUnitCircle * startingCount * AgentDensity,
                Quaternion.Euler(Vector3.forward * Random.Range(0f, 360f)),
                transform
                );
            newAgent.name = "Agent " + i;
            newAgent.Initialize(this);
            agents.Add(newAgent);
        }
    }
예제 #19
0
    // Start is called before the first frame update
    void Start()
    {
        sqrMaxSpeed        = maxSpeed * maxSpeed;
        sqrNeighborRadius  = neighborRadius * neighborRadius;
        sqrAvoidanceRadius = sqrNeighborRadius * avoidanceRadiusMultiplier * avoidanceRadiusMultiplier;

        for (int i = 0; i < startingCount; i++)
        {
            Vector3    direction = new Vector3(Random.Range(0f, 360f), Random.Range(0f, 360f), Random.Range(0f, 360f));
            FlockAgent newAgent  = Instantiate(
                agentPrefab,
                Random.insideUnitSphere * startingCount * agentDensity,
                Quaternion.Euler(direction),
                transform
                );
            newAgent.name = "Agent " + i;
            agents.Add(newAgent);
        }
    }
예제 #20
0
    public override Vector3 CalculateMove(FlockAgent agent, List <Transform> context, Flock flock)
    {
        //if no neighbours, return no adjustment
        if (context.Count == 0)
        {
            return(Vector3.zero);
        }
        //add all points together
        Vector3 cohesionMove = Vector3.zero;

        foreach (Transform item in context)
        {
            cohesionMove += item.position;
        }
        cohesionMove /= context.Count;
        //create offset from agent pos
        cohesionMove -= agent.transform.position;
        return(cohesionMove);
    }
    public override Vector2 CalculateMove(FlockAgent agent, List <Transform> context, Flock flock)
    {
        Vector2 centerOffset = center - (Vector2)agent.transform.position;
        float   t            = centerOffset.magnitude / radius;

        // Debug.Log("T is: " + t);
        // Debug.Log("Mag is: " + centerOffset.magnitude);
        if (t < 0.9f)
        {
            return(Vector2.zero);
        }
        else
        {
            // Debug.Log("Centering");
            Vector2 moveCenter = centerOffset * t * t;
            // Debug.Log(moveCenter);
            return(moveCenter);
        }
    }
예제 #22
0
    public override Vector2 CalculateMove(FlockAgent agent, List <Transform> context, Flock flock, GameObject player)
    {
        // if no neighobers, stay the current course
        if (context.Count == 0)
        {
            return(agent.transform.up);
        }

        // add all the points and average it
        Vector2 AlignmentMove = Vector2.zero;

        foreach (Transform item in context)
        {
            AlignmentMove += (Vector2)item.transform.up;
        }
        AlignmentMove /= context.Count;

        return(AlignmentMove);
    }
예제 #23
0
    public override Vector2 CalculateMovement(FlockAgent agent, List <Transform> neighbors, Flock flock)
    {
        if (neighbors.Count == 0)
        {
            return(Vector2.zero);
        }

        Vector2 cohesionMove = Vector2.zero;

        foreach (Transform item in neighbors)
        {
            cohesionMove += (Vector2)item.position;
        }

        cohesionMove /= neighbors.Count;

        cohesionMove -= (Vector2)agent.transform.position;

        return(cohesionMove);
    }
예제 #24
0
    public override Vector3 CalculateMove(FlockAgent agent, List <Transform> context, Flock flock)
    {
        // if no neighbors, maintain alignment
        if (context.Count == 0)
        {
            return(agent.transform.forward);
        }

        // add all points together and average
        Vector3          alignmentMove   = Vector3.zero;
        List <Transform> filteredContext = (filter == null) ? context : filter.Filter(agent, context);

        foreach (Transform item in filteredContext)
        {
            alignmentMove += item.forward;
        }
        alignmentMove /= context.Count;

        return(alignmentMove);
    }
예제 #25
0
    public override Vector3 CalculateMove(FlockAgent agent, List <Transform> context, Flock flock)
    {
        //if no neighbors, no adjustment
        if (context.Count == 0)
        {
            return(agent.transform.forward);
        }

        Vector3          alignmentMove   = Vector3.zero;
        List <Transform> filteredContext = (filter == null) ? context : filter.Filter(agent, context);

        foreach (Transform item in filteredContext)
        {
            alignmentMove += item.transform.forward; //go where neighbors are going
        }

        alignmentMove /= context.Count;

        return(alignmentMove);
    }
예제 #26
0
    public override Vector2 CalculateMove(FlockAgent agent, List <Transform> context, Flock flock)
    {
        //If no neighbors, maintain current rotation
        if (context.Count == 0)
        {
            return(agent.transform.up);
        }

        //Add all of the neighbor's points together and average them
        Vector2          alignmentMove   = Vector2.zero;
        List <Transform> filteredContext = (filter == null) ? context : filter.Filter(agent, context);

        foreach (Transform item in filteredContext)
        {
            alignmentMove += (Vector2)item.transform.up;
        }
        alignmentMove /= context.Count;

        return(alignmentMove);
    }
    public override Vector2 CalculateMove(FlockAgent agent, List <Transform> context, List <Transform> areaContext, Flock flock)
    {
        Vector2 move = Vector2.zero;

        for (int i = 0; i < Flocks.Length; i++)
        {
            Vector2 partialMove = Flocks[i].behavior.CalculateMove(agent, context, areaContext, flock) * Flocks[i].weight;

            if (partialMove != Vector2.zero)
            {
                if (partialMove.SqrMagnitude() > Flocks[i].weight * Flocks[i].weight)
                {
                    partialMove.Normalize();
                    partialMove *= Flocks[i].weight;
                }
                move += partialMove;
            }
        }
        return(move);
    }
예제 #28
0
    //Another instance of the calculate move from within Flock Behaviour which checks for the center of the game and the size of the predetermined radius
    // it will then use this data to try and stay within that radius using the return percent to decide how successful this is and how often
    public override Vector2 CalculateMove(FlockAgent agent, List <Transform> context, List <Transform> areaContext, Flock flock)
    {
        //Direction towards center
        Vector2 centreOffset = center - (Vector2)agent.transform.position;

        //Distance to center
        float t = centreOffset.magnitude / radius;

        if (t < returnPercent)
        {
            return(Vector2.zero);
        }

        return(centreOffset);
        // * Variations:
        //or
        //return centreOffset * t;
        //or
        //return centreOffset * t * t;
    }
예제 #29
0
    // Start is called before the first frame update
    void Start()
    {
        squareMaxSpeed        = maxSpeed * maxSpeed;
        squareNeighborRadius  = UIDataAccessor.Instance.GetGroupingForceData().radius;
        squareAvoidanceRadius = UIDataAccessor.Instance.GetCollisionAvoidanceData().minDistance;
        squareObstacleRadius  = UIDataAccessor.Instance.GetObstacleAvoidanceData().radius;

        for (int i = 0; i < startingCount; i++)
        {
            FlockAgent newAgent = Instantiate(
                agentPrefab,
                Random.insideUnitCircle * startingCount * AgentDensity,
                Quaternion.Euler(Vector3.forward * Random.Range(0f, 360f)),
                transform
                );
            newAgent.name = "Agent " + i;
            newAgent.Initialize(this);
            agents.Add(newAgent);
        }
    }
    public override Vector3 CalculateMove(FlockAgent agent, List <Transform> context, Flock flock)
    {
        if (context.Count == 0) // No neighbours, no adjustment
        {
            return(Vector3.zero);
        }

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

        foreach (Transform item in context)
        {
            cohesionMove += item.position;
        }
        cohesionMove /= context.Count;

        // Create offset
        cohesionMove -= agent.transform.position;
        return(cohesionMove);
    }
 /* public function to add fAgents
 *	NOTE1: for simplicity i do not check
 *		if the object is not in the list
 *
 *	NOTE2: This is never called in-game
   */
 public void UnRegister( FlockAgent self)
 {
     fAgents.Remove (self);
     totalFAgents -= 1;
 }
 /* public function to add fAgents
 *	NOTE: for simplicity i do not check
 *		if the object is already in the list
   */
 public void Register( FlockAgent self )
 {
     fAgents.Add (self);
     totalFAgents += 1;
 }
    /* The bread and butter of this whole script
    *	Calculates the 5 rules
    *		Cohesion - flock towards center of mass
    *		Seperation - avoid other flock units
    *		Alignment - flock towards general direction
    *		Bounds - avoid leaving the bounds of the map
    *		playerAvoid - avoid the player unless swarm is true
    *
    *	then we aggregate all the rules into the future velocity
    */
    void Update()
    {
        for(int i = 0; i < totalFAgents ; i++)
        {
            _currentFlockAgent = fAgents[i];
            cohesion.Set (0f, 0f, 0f);
            seperation.Set (0f, 0f, 0f);
            alignment.Set (0f, 0f, 0f);
            bounds.Set (0f,0f,0f);
            futureVelocity.Set (0f, 0f,0f);
            neighborCount = 0;

            for(int j = 0; j < totalFAgents; j++)
            {
                _compareFlockAgent = fAgents[j];

                if(_compareFlockAgent != _currentFlockAgent)
                {
                    diffVector = _compareFlockAgent._transform.position - _currentFlockAgent._transform.position;
                    distanceSqr = diffVector.sqrMagnitude;
                    if(  distanceSqr <= flockDistance  )
                    {
                        cohesion +=  _compareFlockAgent._transform.position;
                        alignment += _compareFlockAgent._rigidbody.velocity;
                        neighborCount++;
                        if(distanceSqr <= startSeperationDistance )
                        {
                            seperation -= diffVector;
                        }
                    }
                }
            }

            bounds = Vector3.Normalize( BoundsCheck(_currentFlockAgent._transform.position) );

            if(neighborCount > 0)
            {
                cohesion = ( ((cohesion / neighborCount)) - _currentFlockAgent._transform.position);
                alignment = ( alignment / neighborCount);
                seperation =  Vector3.Normalize ( seperation );
            }

            if(PlayerInfo.Player != null)
            {
                playerAvoid = PlayerInfo.Player._transform.position - _currentFlockAgent._transform.position;

                if(playerAvoid.sqrMagnitude <= playerAvoidanceDistance)
                {
                    if(bSwarm)
                    {
                        playerAvoid *= -1;
                    }

                    cohesion = (cohesion) - (playerAvoid * playerAvoidanceMult);
                }
            }

            futureVelocity = (alignment * alignmentMult) + (seperation * seperationMult) + (cohesion * cohesionMult) + _currentFlockAgent._rigidbody.velocity + bounds;

            if( futureVelocity.sqrMagnitude > flockMaxVelocity)
            {
                _currentFlockAgent._rigidbody.velocity = Vector3.ClampMagnitude( futureVelocity, Mathf.Sqrt(flockMaxVelocity) );
            }
            else
            {
                _currentFlockAgent._rigidbody.velocity = futureVelocity;
            }
        }
    }