Ejemplo n.º 1
0
    // Update is called once per frame - NOTE: shooting timing should probably be done in fixed update, so that gun firing is not FPS dependent.. But oh well handle that shit when you do it properly.
    void Update()
    {
        // If we are 'reacting', that means that we just spotted a new target. After 'reaction time' has elapsed, the newTarget will become the current target, and the 'newTarget' becomes null.
        if (reacting && Time.time >= nextReactTime)
        {
            //REACT!
            reacting      = false;
            currentTarget = newTarget;
            newTarget     = null;

            // Invoke the target engaged event!
            if (currentTarget != null)
            {
                EnemyEngagedEvent?.Invoke(this, currentTarget);
            }

            // If the target is further away than the stand still threshold, then we should stop moving to aim carefully!
            prevTargetDistance = Vector3.Distance(transform.position, currentTarget.collider.transform.position);
            if (prevTargetDistance > standStillThreshold)
            {
                agent.isStopped = true;  // Pause the agent's path.
            }
        }

        // If we have a target, then rather than just walking around, we should lookat, and shoot at, our target! If the target info contains a null reference we assume our target was destroyed.
        if (currentTarget != null)
        {
            // Check if the target has been killed. If so, reset the current target.
            if (!TargetStillAlive(currentTarget))
            {
                currentTarget = null;
            }
            // We have a target, and that target is still alive! Let's continue our logic.
            else
            {
                AimTowardsTarget(currentTarget);

                // If the target was previously inside our distance threshold, and just moved outside of it this tick, then we should stop moving and aim carefully.
                float currDist = Vector3.Distance(transform.position, currentTarget.collider.transform.position);
                if (prevTargetDistance <= standStillThreshold && currDist > standStillThreshold)
                {
                    agent.isStopped = true;  // Pause the agent's path.
                }
                else if (currDist < standStillThreshold)
                {
                    agent.isStopped = false; // Resume walking if the target get's too close!
                }

                AttemptToShoot(currentTarget);
                prevTargetDistance = currDist;
            }
        }
        else
        {
            agent.isStopped = false;   // Resume walking if there is no target to worry about!
            AimTowardsWalkDirection(); // Turn the body back in the direction of the nav agent's facing direction!
        }
    }
    // This function is the Event handler we register to receive updates from the Combat Ai. It is called when the combat ai decides to engage a particular enemy.
    private void HandleEnemyEngagedEvent(object sender, TargetInformation enemy)
    {
        if (!enemy.IsCharacter)
        {
            return;
        }

        if (!enemiesAwareOf.ContainsKey(enemy.character))
        {
            enemiesAwareOf.Add(enemy.character, AwarenessStates.EngagedWith);
            EnemyEngagedEvent?.Invoke(this, enemy.character);
        }
        else if (enemiesAwareOf[enemy.character] != AwarenessStates.EngagedWith)
        {
            enemiesAwareOf[enemy.character] = AwarenessStates.EngagedWith;
            EnemyEngagedEvent?.Invoke(this, enemy.character);
        }
        else
        {
            // Do nothing. Our internal state seems to think we are already engaging this target. Why are we recieving this event.. ? (Check for timing bugs?)
        }
    }