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); }
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); }
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);
public void AddAgent(FlockAgentDynamic newAgent) { agents.Add(newAgent); }