/** * Updates the movement direction (see NavAgentHelper) according to the * pheromones located near the agent. * * Combat/Harvest pheromones are only taken into account, if the task of the agent * is combat and harvest respectively. * * Also: Combat/Harvest pheromones are ignored in certain states. Repellant pheromones * are taken into account in every state. */ void Update() { _currentSmellAngleCos = Mathf.Cos(_agentConfiguration.smellAngle); UpdatePheromoneSensor(); Vector3 attractionDirection = new Vector3(); if (_states.IsIdling()) { _previousState = EAntStates.Idle; } // Only take harvest/combat pheromones into account if the agent is idling or following pheromones. if (_states.IsIdling() || _states.IsFollowingPheromone()) { if (_states.GetTask() == EAntTasks.HarvestFood && _previousState != EAntStates.ReturnToBase) { attractionDirection = AggregateMovementDirection(EPheromoneTypes.Food); } else if (_states.GetTask() == EAntTasks.Attack) { attractionDirection = AggregateMovementDirection(EPheromoneTypes.Attack); } } // Always take repellant pheromones into account. Vector3 repulsionDirection = AggregateMovementDirection(EPheromoneTypes.Repellant); // If pheromones influence movement direction, set this direction and switch // to pheromone following state if necessary. if (attractionDirection.sqrMagnitude > 0f || repulsionDirection.sqrMagnitude > 0f) { _navHelper.SetDirection(0.01f * attractionDirection + 0.99f * repulsionDirection); if (!_states.IsFollowingPheromone()) { // Save the current state so we can restore status quo lateron. _previousState = _states.currentState; _states.currentState = EAntStates.FollowPheromone; } } // Switch back to previous state, if no longer following pheromones. else if (_states.IsFollowingPheromone()) { _states.currentState = _previousState; } // Debug.DrawLine (transform.position, transform.position + Quaternion.Euler(0f, GlobalAntConfiguration.smellAngle * Mathf.Rad2Deg, 0f) * transform.forward * _currentSmellDistance); // Debug.DrawLine (transform.position, transform.position + Quaternion.Euler(0f, -GlobalAntConfiguration.smellAngle * Mathf.Rad2Deg, 0f) * transform.forward * _currentSmellDistance); }
void PossibleTargetInTrigger(Collider collider) { // If the agent is not in combat task, do nothing. if (_states.GetTask() != EAntTasks.Attack) { return; } // Notify attack script about new target. _attack.AcquireNewTarget(collider.gameObject); // Change to combat state (which may be left immediately, see AgentCombat). if (_states.GetTask() == EAntTasks.Attack) { _states.currentState = EAntStates.Combat; } }
/** * Begin to harvest the resource. * * This method is called by the AgentResourceSensor when it detects a * resource. */ public void StartHarvesting(Collider other) { if (_states.GetTask() != EAntTasks.HarvestFood) { return; } ResourceSource resourceSource = other.GetComponent <ResourceSource> (); if (resourceSource) { _navHelper.SetDirection(other.transform.position - transform.position); _currentSource = resourceSource; _inventory.resourceType = resourceSource.resourceType; _harvestTimer = 0.0f; _states.currentState = EAntStates.Harvesting; } }
// Update is called once per frame void Update() { // Check if another task was assigned. In this case, // combat mode should be left. if (_states.GetTask() != EAntTasks.Attack) { _states.currentState = EAntStates.Idle; return; } // If changed to combat mode if (_attack.HasTarget() && !_inCombat) { _inCombat = true; _pheromonePlacement.SetPheromoneType(EPheromoneTypes.Attack); return; } // If target was lost (and possibly was in combat mode) if (!_attack.HasTarget()) { _inCombat = false; _states.currentState = EAntStates.Idle; return; } // We are in combat so update combat circling. if (_inCombat) { GameObject target = _attack.GetCurrentTarget(); Vector3 distance = target.transform.position - transform.position; // Only change circle if we risk to lose the target. if (distance.magnitude > (_randomRadius - 0.2)) { DoCombatCircling(); } } }