Exemple #1
0
    private void Update()
    {
        Vector3 muzzlePos        = muzzle.position;
        float   reticleDistance  = defaultReticleDistance;
        float   yawAngle         = GetYawAngle();
        float   pitchAngle       = GetPitchAngle();
        float   targetYawAngle   = 0;
        float   targetPitchAngle = 0;
        Vector3 targetPoint      = Vector3.zero;

        if (m_target == null || !m_target.Alive || !TryComputeAnglesToTarget(out targetYawAngle, out targetPitchAngle, targetPoint = m_target.GetAimPoint()))
        {
            // No target or lost target -- try to acquire a new one
            m_lockedOn = false;
            m_target   = null;
            Destructible[]   enemies     = GameObject.FindObjectsOfType <Destructible>();
            MathHelpers.Cone aimingCone  = new MathHelpers.Cone(muzzlePos, muzzle.forward, 1.5f, 45);
            float            minDistance = float.PositiveInfinity;

            foreach (Destructible enemy in enemies)
            {
                if (!enemy.gameObject.CompareTag("Enemy") || !enemy.Alive)
                {
                    continue;
                }
                Vector3 enemyPos = enemy.GetAimPoint();
                float   distanceFromAxis;
                if (aimingCone.Contains(enemyPos) && (distanceFromAxis = aimingCone.DistanceFromAxis(enemyPos)) < minDistance)
                {
                    minDistance = distanceFromAxis;
                    m_target    = enemy;
                }
            }

            // Try to compute aiming angles for new target
            if (m_target != null && !TryComputeAnglesToTarget(out targetYawAngle, out targetPitchAngle, targetPoint = m_target.GetAimPoint()))
            {
                m_target = null;
            }
        }

        // If we are not locked on, take a step toward new angles
        if (!m_lockedOn)
        {
            float angleStep       = angularVelocity * Time.deltaTime;
            float deltaYawAngle   = targetYawAngle - yawAngle;
            float deltaPitchAngle = targetPitchAngle - pitchAngle;
            yawAngle   += deltaYawAngle >= 0 ? Mathf.Min(angleStep, deltaYawAngle) : Mathf.Max(-angleStep, deltaYawAngle);
            pitchAngle += deltaPitchAngle >= 0 ? Mathf.Min(angleStep, deltaPitchAngle) : Mathf.Max(-angleStep, deltaPitchAngle);
            if (m_target != null && Mathf.Abs(targetPitchAngle - pitchAngle) < 1e-1f && Mathf.Abs(targetYawAngle - yawAngle) < 1e-1f)
            {
                m_lockedOn = true;
            }
        }
        else
        {
            // When locked on, instaneously track target
            yawAngle        = targetYawAngle;
            pitchAngle      = targetPitchAngle;
            reticleDistance = Vector3.Distance(targetPoint, muzzlePos);
        }

        // Update gun orientation
        if (gunYaw == gunPitch)
        {
            gunYaw.localRotation = Quaternion.Euler(pitchAngle, yawAngle, 0);
        }
        else
        {
            gunYaw.localRotation   = Quaternion.Euler(0, yawAngle, 0);
            gunPitch.localRotation = Quaternion.Euler(pitchAngle, 0, 0);
        }

        if (targetingReticle != null)
        {
            targetingReticle.LockedOn           = m_lockedOn;
            targetingReticle.transform.position = muzzlePos + muzzle.forward * reticleDistance;
        }
    }