/*
     * // When the flock creates the agent, link the agent to the flock.
     * public void Initialize(FlockDynamic flock)
     * {
     *  agentFlock = flock;
     * }
     */

    // Assign this agent to a new flock.
    public void AssignToFlock(FlockDynamic flock)
    {
        agentFlock = flock;
        flock.AddAgent(this);
    }
Exemplo n.º 2
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);
    }
Exemplo n.º 3
0
 public abstract Vector3 CalculateMove(FlockAgentDynamic agent, List <Transform> context, FlockDynamic flock);
    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);
    }
    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);
    }
    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);
    }