void Awake() { _pheromoneManager = (PheromoneManager)Object.FindObjectOfType(typeof(PheromoneManager)); _agentConfiguration = FindObjectOfType(typeof(GlobalAgentConfiguration)) as GlobalAgentConfiguration; _type = EPheromoneTypes.Food; }
public void Initialize(EPheromoneTypes type, float intensity, float diameter, float diffusionRate, float minimumConcentration, Color color) { this.type = type; _startIntensity = intensity; _diffusionRate = diffusionRate; _minimumConcentration = minimumConcentration; _diffusionSphere.transform.localScale = new Vector3(diameter, diameter, diameter); // max radius = (n / (3/4 * PI * c))^(1/3) float maxRadius = Mathf.Pow(_startIntensity / (0.75f * Mathf.PI * _minimumConcentration), 1f / 3f); float ttl = maxRadius / _diffusionRate; // Initialize particle system _particleSystem.startLifetime = ttl; //Mathf.Pow ((0.75f * _startIntensity) / (_minimumConcentration * Mathf.PI), 1f / 3f) / diffusionRate + 3.0f; _particleSystem.startSpeed = diffusionRate * 0.5f; _particleSystem.startColor = color; ParticleSystem.EmissionModule emission = _particleSystem.emission; emission.rate = new ParticleSystem.MinMaxCurve(0f); ParticleSystem.ShapeModule shape = _particleSystem.shape; shape.radius = diameter * 0.5f; _particleSystem.Emit((int)(50.0f * _startIntensity)); _currentVisibility = true; RecalculateCurrentConcentration(); UpdateVisibility(); }
/** * Place a pheromone of given type at given position. * * If necessary, merge it with existing pheromones. A merge is triggered if more than * 4 pheromones are located at the same position, i.e. their centers lie within a circle of 0.5 units. */ public void PlacePheromone(Vector3 position, EPheromoneTypes type) { position.y = 0; PheromoneConfiguration pheromoneConfiguration = _pheromoneConfiguration.configs [type]; // Get current parameters from configuration. float initialIntensity = pheromoneConfiguration.initialIntensity; float initialScale = pheromoneConfiguration.initialRadius; float diffusionRate = pheromoneConfiguration.diffusionRate; float minimumConcentration = pheromoneConfiguration.minimumConcentration; Color color = pheromoneConfiguration.color; // If there are enough pheromones nearby, merge them into one Collider[] nearbyPheromoneCenters = Physics.OverlapSphere(position, 0.5f, _pheromoneOriginLayerMask); List <GameObject> nearbyPheromones = new List <GameObject> (); // Filter nearby pheromones by type. foreach (Collider pheromoneCenter in nearbyPheromoneCenters) { GameObject pheromone = pheromoneCenter.transform.parent.gameObject; if (pheromone.GetComponent <Pheromone> ().type == type) { nearbyPheromones.Add(pheromone); } } // Merge if enough pheromones of the same type are located on position. if (nearbyPheromones.Count > 4) { foreach (GameObject pheromone in nearbyPheromones) { initialIntensity += pheromone.GetComponent <Pheromone>().startIntensity; initialScale = Mathf.Max(initialScale, pheromone.transform.Find("DiffusionSphere").transform.localScale.x); //startScale += pheromone.transform.Find ("DiffusionSphere").transform.localScale.x; position += pheromone.transform.position; Destroy(pheromone); } // Make start scale the average of all scales //startScale = startScale / (nearbyPheromoneCenters.GetLength(0) + 1); position = position / (nearbyPheromones.Count + 1); } // Create and initialize new pheromone GameObject newPheromone = Instantiate(_pheromonePrefab, position, new Quaternion()) as GameObject; newPheromone.GetComponent <Pheromone>().Initialize(type, initialIntensity, initialScale, diffusionRate, minimumConcentration, color); }
public void Activate(EPheromoneTypes pheromoneType) { gameObject.SetActive(true); _pheromoneType = pheromoneType; foreach (Transform row in transform) { foreach (Transform child in row) { PotentialFieldElement element = child.GetComponent <PotentialFieldElement> (); if (element) { element.pheromoneType = _pheromoneType; } } } }
/** * Calculate attraction (or repulsion) for a given pheromone type. The resulting * vector is the (negative) gradient and thus the direction the agent moves to. * * @param pheromoneType The type of the pheromone for which the direction / gradient should be calculated. * @return The direction in which the agent should move. */ Vector3 AggregateMovementDirection(EPheromoneTypes pheromonType) { HashSet <Pheromone> pheromones = _nearbyPheromones [pheromonType]; Vector3 movementVector = new Vector3(); Vector3 position = transform.position; position.y = 0.0f; foreach (Pheromone pheromone in pheromones) { // Ensure that no destroyed pheromones are accessed. if (!pheromone) { continue; } Vector3 pheromonePosition = pheromone.transform.position; pheromonePosition.y = 0.0f; Vector3 pheromoneVector = (pheromonePosition - position).normalized; float pheromoneAngleCosine = Vector3.Dot(transform.forward, pheromoneVector); // Check if pheromone is "in front of" the agent. if (pheromoneAngleCosine > _currentSmellAngleCos) { movementVector += pheromoneVector * pheromone.currentConcentration; } } // If the pheromone is repellant, return the negative movement vector. if (pheromonType == EPheromoneTypes.Repellant) { return(-movementVector); } return(movementVector); }
/** * Set the type of pheromones that should be deposited. * * This is set by other components according to the current task and state of the agent. */ public void SetPheromoneType(EPheromoneTypes type) { _type = type; }
public bool IsActiveWith(EPheromoneTypes pheromoneType) { return(gameObject.activeInHierarchy && _pheromoneType == pheromoneType); }