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; } }