/**
     * 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);
    }
예제 #2
0
    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;
        }
    }
예제 #3
0
    /**
     * 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;
        }
    }
예제 #4
0
    // 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();
            }
        }
    }