public override Vector3 CalculateMove(FlockAgentDynamic agent, List <Transform> context, FlockDynamic flock)
    {
        // If no neighbours, don't adjust position.
        if (context.Count == 0)
        {
            return(Vector3.zero);
        }

        // Find the middle point of all neighbours, and move there.
        // 1. Add all context points together.
        Vector3 cohesionMove = Vector3.zero;

        // Check if a filter is applied. If the filter is null, use normal context. If there is a filter, use the filter.
        List <Transform> filteredContext = (filter == null) ? context : filter.Filter(agent, context);

        foreach (Transform item in filteredContext)
        {
            cohesionMove += item.position;
        }
        // 2. Average all points.
        cohesionMove /= context.Count;

        // 3. Calculate the offset from the agent's position.
        cohesionMove -= agent.transform.position;
        return(cohesionMove);
    }
    List <Transform> GetNearbyObjects(FlockAgentDynamic agent)
    {
        distanceToClosest = Mathf.Infinity;

        List <Transform> context = new List <Transform>();

        // Get an array of all colliders in a the radius, using OverlapSphere.
        Collider[] contextColliders = Physics.OverlapSphere(agent.transform.position, neighbourRadius);
        //Collider2D[] contextColliders = Physics2D.OverlapCircleAll(agent.transform.position, neighbourRadius);

        foreach (Collider collider in contextColliders)
        {
            // Add all of the transforms of the colliders in the sphere, except this object's (agent's) transform.
            if (collider != agent.AgentCollider && collider.tag != "Ground")
            {
                context.Add(collider.transform);
                float dist = Vector3.Distance(transform.position, collider.transform.position);
                if (dist < distanceToClosest)
                {
                    distanceToClosest = dist;
                    closestObject     = collider;
                }
            }
        }
        return(context);
    }
    public override Vector3 CalculateMove(FlockAgentDynamic agent, List <Transform> context, FlockDynamic flock)
    {
        // If no neighbours, maintain current alignment.
        if (context.Count == 0)
        {
            return(agent.transform.forward);
        }

        // Find the alignment of all neighbours and align agent according to their average alignment.
        // 1. Add all context points together.
        Vector3 alignmentMove = Vector3.zero;

        // Check if a filter is applied. If the filter is null, use normal context. If there is a filter, use the filter.
        List <Transform> filteredContex = (filter == null) ? context : filter.Filter(agent, context);

        foreach (Transform item in filteredContex)
        {
            alignmentMove += item.transform.forward;
        }
        // 2. Average all points.
        alignmentMove /= context.Count;

        // The alignment is independent of the position, so there is no need to create an offset.
        return(alignmentMove);
    }
    public override List <Transform> Filter(FlockAgentDynamic agent, List <Transform> original)
    {
        List <Transform> filtered = new List <Transform>();

        // Check if a transform is on the filtered physics layer.
        foreach (Transform item in original)
        {
            // If this is true, then the item we're checking is on the same layer as the mask is checking.
            if (mask == (mask | (1 << item.gameObject.layer)))
            {
                filtered.Add(item);
            }
        }
        return(filtered);
    }
    public override List <Transform> Filter(FlockAgentDynamic agent, List <Transform> original)
    {
        List <Transform> filtered = new List <Transform>();

        // Iterate through the original list, and determine if a new transform has the FlockAgent component AND is of the same flock.
        // If both are true, add to the list of filtered transforms.
        foreach (Transform item in original)
        {
            FlockAgentDynamic itemAgent = item.GetComponent <FlockAgentDynamic>();
            if (itemAgent != null && itemAgent.AgentFlock == agent.AgentFlock)
            {
                filtered.Add(item);
            }
        }
        return(filtered);
    }
    public override Vector3 CalculateMove(FlockAgentDynamic agent, List <Transform> context, FlockDynamic flock)
    {
        // Calculate the position of the agent in relation to the cneter.
        Vector3 centerOffset = center - agent.transform.position;

        // t is the magnitude of distance from the center.
        // t = 0 -> agent is at the center, t = 1 -> agent is at the radius parameter.
        float t = centerOffset.magnitude / circleRadius;

        // If not close to the radiu edge, continue as normal.
        if (t < 0.9f)
        {
            return(Vector3.zero);
        }

        // If close to the radius edge, start moving towards the center.
        return(centerOffset * t * t);
    }
    public override Vector3 CalculateMove(FlockAgentDynamic agent, List <Transform> context, FlockDynamic flock)
    {
        // Throw an error if the number of behaviors doesn't match the number of weights, and don't move the agent.
        if (weights.Length != behaviors.Length)
        {
            Debug.LogError("Data mismatch in " + name, this);
            return(Vector3.zero);
        }

        // Set up the combined move of all behaviors.
        Vector3 move = Vector3.zero;

        // Iterate through behaviors. Use a 'for' loop and not 'foreach' to match the index of the bahavior to the index of the weight.
        for (int i = 0; i < behaviors.Length; i++)
        {
            // Call on the CalculateMove of each behavior based on its weight.
            Vector3 partialMove = behaviors[i].CalculateMove(agent, context, flock) * weights[i];

            // Confirm that the partial move is limited to the extent of the weight.
            // If there is some movement...
            if (partialMove != Vector3.zero)
            {
                // If the partial movement exceeds the weight...
                if (partialMove.sqrMagnitude > weights[i] * weights[i])
                {
                    // Then normalize the partial move to a magnitude of one and multiply by the weight, to set it to the max of the weight.
                    partialMove.Normalize();
                    partialMove *= weights[i];
                }

                // If the partial move doesn't exceed the weight, conduct the partial move.
                move += partialMove;
            }
        }

        return(move);
    }
示例#8
0
    public override Vector3 CalculateMove(FlockAgentDynamic agent, List <Transform> context, FlockDynamic flock)
    {
        // If no neighbours, don't adjust position.
        if (context.Count == 0)
        {
            return(Vector3.zero);
        }

        // Find the middle point of all items to avoid, and move away from them.
        Vector3 avoidanceMove = Vector3.zero;

        // Create an int for number of things to avoid.
        int nAvoid = 0;

        // Check if a filter is applied. If the filter is null, use normal context. If there is a filter, use the filter.
        List <Transform> filteredContex = (filter == null) ? context : filter.Filter(agent, context);

        foreach (Transform item in filteredContex)
        {
            // Get the distance between the agent and the item to avoid.
            // If item is in avoidance distance (distance to item < distance to avoid), add to items to avoid..
            if (Vector3.SqrMagnitude(item.position - agent.transform.position) < flock.SquareAvoidanceRadius)
            {
                nAvoid++;
                // Calculate the offset and move away from the item.
                avoidanceMove += agent.transform.position - item.position;
            }
        }

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

        return(avoidanceMove);
    }
示例#9
0
 public abstract Vector3 CalculateMove(FlockAgentDynamic agent, List <Transform> context, FlockDynamic flock);
 // Compare a new transform against the original list of transforms.
 public abstract List <Transform> Filter(FlockAgentDynamic agent, List <Transform> original);
示例#11
0
 public void AddAgent(FlockAgentDynamic newAgent)
 {
     agents.Add(newAgent);
 }