private void SetTargetEnemy(EnemyContact target)
    {
        if (m_currentTarget == target)
        {
            return;
        }

        m_currentTarget = target;
        m_targetSeekT   = m_targetSeekInterval;

        if (target != null && target.m_entity != null)
        {
            //Debug.LogWarning(DebugUtilities.AddTimestampPrefix(GetType() + ": New target set: " + target.m_entity.name + ", threat=" + target.m_threat), target.m_entity);
            DebugUtilities.DrawArrow(transform.position, target.Position, Vector3.back, Color.red, 0, 1f);
        }
        //else
        //Debug.LogWarning(DebugUtilities.AddTimestampPrefix(GetType() + ": Target cleared"));
    }
    private EnemyContact FindHighestThreat()
    {
        EnemyContact currentEnemyContact = null;

        foreach (EnemyContact ec in m_enemies.Values)
        {
            if (ec.m_wasShotAt)
            {
                continue;
            }

            if (currentEnemyContact == null || ec.m_threat > currentEnemyContact.m_threat)
            {
                currentEnemyContact = ec;
            }
        }

        return(currentEnemyContact);
    }
    protected override void Update()
    {
        if (!m_canControl)
        {
            return;
        }

        if (m_pendingContacts.Count > 0)
        {
            foreach (Entity entity in m_pendingContacts)
            {
                float speed, timeToTarget;
                if (entity is Projectile)
                {
                    Projectile p = entity as Projectile;
                    speed        = p.Speed;
                    timeToTarget = Vector3.Distance(entity.transform.position, p.TargetPosition) / p.Speed;
                }
                else
                {
                    speed        = 0f;
                    timeToTarget = -1f;
                }

                EnemyContact newEnemy = new EnemyContact(entity, speed, timeToTarget);
                m_enemies.Add(entity.ID, newEnemy);

                if (m_currentTarget == null || m_currentTarget.m_entity == null)
                {
                    SetTargetEnemy(newEnemy);
                }
            }

            m_pendingContacts.Clear();
        }

        foreach (EnemyContact ec in m_enemies.Values)
        {
            ec.m_timeToTarget -= Time.deltaTime;
            ec.m_threat        = ec.m_timeToTarget > 0f ? 1f / (ec.m_timeToTarget) : 0f;
        }

        if (m_scanT <= 0f)
        {
            if (m_currentTarget == null || m_currentTarget.m_entity == null)
            {
                m_scanT = m_scanInterval;
                SetTargetEnemy(FindHighestThreat());
            }
        }
        else
        {
            m_scanT -= Time.deltaTime;
        }

        if (m_currentTarget != null && m_currentTarget.m_entity != null)
        {
            Vector3 targetPosition;
            bool    solutionFound = false;
            if (Math3D.TryGetInterceptPoint(transform.position, Vector3.zero, m_projectileSpeed, m_currentTarget.Position, m_currentTarget.Velocity, out targetPosition))
            {
                solutionFound = targetPosition.y > ScenarioManager.GameArea.yMin && targetPosition.y < ScenarioManager.GameArea.yMax;
            }

            if (solutionFound)
            {
                SetTarget(targetPosition);
            }

            if (m_targetSeekT <= 0f)
            {
                if (solutionFound && m_canFire)
                {
                    m_turret.OnFireCommand(true);
                    m_currentTarget.m_wasShotAt = true;
                    m_currentTarget             = null;
                    m_targetSeekT = m_targetSeekInterval;
                }
            }
            else
            {
                m_targetSeekT -= Time.deltaTime;
            }
        }
    }