/*void Update()
     * {
     *  gun.LookAt(playerCamera.GetTargetPosition());
     *
     *  if (playerScript.Paused)
     *      bulletsLeft = BurstCount;
     * }*/

    // TODO unused, looks like it should go below in the homing firing
    //WeaponIndicatorScript.PlayerData GetFirstTarget()
    //{
    //    var aimedAt = targets.Where(x => x.SinceInCrosshair >= AimingTime );
    //    return aimedAt.OrderBy( x => Guid.NewGuid() ).First();
    //}

    public void Update()
    {
        var actualTargetPosition = playerCamera.GetTargetPosition();

        firingDirection = (actualTargetPosition - gun.transform.position).normalized;
        var gunRotationAngles  = Quaternion.FromToRotation(Vector3.forward, firingDirection).eulerAngles;
        var desiredGunRotation = Quaternion.Euler(gunRotationAngles.x, gunRotationAngles.y, 0);

        gun.transform.rotation = Quaternion.Slerp(gun.transform.rotation, desiredGunRotation,
                                                  1.0f - Mathf.Pow(GunRotationSmoothingSpeed, -GunRotationSmoothingSpeed * Time.deltaTime));
        var doReload = false;

        // Update local position of barrel from recoil
        foreach (var impulse in GunRecoilThrotter.Update())
        {
            GunRecoilSpring.AddImpulse(impulse);
        }
        GunRecoilSpring.Update();
        Vector3 barrelLocalPosition = BarrelTransform.localPosition;

        barrelLocalPosition.z         = GunRecoilSpring.CurrentValue;
        BarrelTransform.localPosition = barrelLocalPosition;

        // Reload spring
        foreach (var impulse in ReloaderDelayer.Update())
        {
            ReloaderSpring.AddImpulse(impulse);
        }
        ReloaderSpring.Update();
        Vector3 reloadLocalPosition = ReloaderTransform.localPosition;

        reloadLocalPosition.z           = ReloaderSpring.CurrentValue;
        ReloaderTransform.localPosition = reloadLocalPosition;

        if (playerScript.Paused)
        {
            bulletsLeft = BurstCount;
        }

        if (networkView.isMine && playerScript.lockMouse && !playerScript.Paused)
        {
            cooldownLeft = Mathf.Max(0, cooldownLeft - Time.deltaTime);
            heat         = Mathf.Clamp01(heat - (Time.deltaTime * HeatCooldownScale));
            weaponIndicator.CooldownStep = 1 - Math.Min(Math.Max(cooldownLeft - ShotCooldown, 0) / ReloadTime, 1);

            if (cooldownLeft <= Mathf.Epsilon)
            {
                // Shotgun
                if (Input.GetButton("Alternate Fire"))
                {
                    OnShotFired();
                    OnShotgunFired();

                    // Rail shot
                    if (bulletsLeft == BurstCount && playerCamera.IsZoomedIn)
                    {
                        DoRailShot();
                        bulletsLeft   = 0;
                        cooldownLeft += ReloadTime * 2.7f;

                        var recoilImpulse = -playerCamera.LookingDirection * 2.35f;
                        recoilImpulse   *= playerScript.controller.isGrounded ? 25 : 87.5f;
                        recoilImpulse.y *= playerScript.controller.isGrounded ? 0.1f : 0.375f;
                        playerScript.AddRecoil(recoilImpulse);
                    }

                    // Homing/shotgun
                    else
                    {
                        // find homing target(s)
                        var aimedAt = targets.Where(x => x.SinceInCrosshair >= AimingTime).ToArray();

                        var bulletsShot = bulletsLeft;
                        var first       = true;
                        int homingFired = 0;
                        while (bulletsLeft > 0)
                        {
                            if (!aimedAt.Any())
                            {
                                DoHomingShot(ShotgunSpread, null, 0, first);
                            }
                            else
                            {
                                var pd = aimedAt.OrderBy(x => Guid.NewGuid()).First();
                                DoHomingShot(ShotgunSpread, pd.Script, Mathf.Clamp01(pd.SinceInCrosshair / AimingTime) * ShotgunHomingSpeed, first);
                                homingFired++;
                            }

                            cooldownLeft += ShotCooldown;
                            first         = false;
                        }
                        cooldownLeft += ReloadTime;

                        float lockOnReduction      = (float)homingFired / (float)BurstCount;
                        float amountOfLockToRemove = WeaponIndicatorScript.PlayerData.LockStrengthLimitMultiplier *
                                                     lockOnReduction;
                        for (int i = 0; i < targets.Count; i++)
                        {
                            targets[i].LockStrength -= amountOfLockToRemove;
                            targets[i].ClampStrength();
                        }

                        var recoilImpulse = -gun.forward * ((float)bulletsShot / BurstCount);
                        recoilImpulse   *= playerScript.controller.isGrounded ? 25 : 87.5f;
                        recoilImpulse.y *= playerScript.controller.isGrounded ? 0.1f : 0.375f;
                        playerScript.AddRecoil(recoilImpulse);

                        float cosmeticAmount = (float)bulletsShot / (float)BurstCount;
                        playerCamera.AddGunShotImpulse(Mathf.Lerp(0.0f, 2.0f, cosmeticAmount));
                        AddGunImpulse(cosmeticAmount);
                    }

                    //cannonChargeCountdown = CannonChargeTime;
                }

                // Burst
                else if (Input.GetButton("Fire")) // burst fire
                {
                    //OnShotFired();

                    DoShot(BurstSpread);
                    cooldownLeft += CurrentShotCooldown;
                }

                if (Input.GetButton("Reload") || bulletsLeft <= 0)
                {
                    doReload = true;
                }
            }

            if (Input.GetButtonUp("Fire"))
            {
                doReload = true;
            }

            if (doReload && bulletsLeft != BurstCount)
            {
                cooldownLeft += ReloadTime * (float)(BurstCount - bulletsLeft) / (float)BurstCount;
                bulletsLeft   = BurstCount;
                if (GlobalSoundsScript.soundEnabled)
                {
                    reloadSound.Play();
                }
                AddReloadImpulse();
            }

            TestScreenSpaceLockTargets();
            CheckTargets();

            // Update weapon indicator bullets count. Kind of hacky because
            // bullet availability is not tracked like you might expect it to
            // be.
            weaponIndicator.BulletCapacity = BurstCount;
            if (bulletsLeft == BurstCount && cooldownLeft >= Mathf.Epsilon)
            {
                weaponIndicator.BulletsAvailable = 0;
            }
            else if (cooldownLeft > Mathf.Epsilon && weaponIndicator.BulletsAvailable < bulletsLeft)
            {
                // Do nothing, probably reloading
            }
            else
            {
                weaponIndicator.BulletsAvailable = bulletsLeft;
            }
        }
    }
Ejemplo n.º 2
0
    public void LateUpdate()
    {
        if (!mainCamera)
        {
            return;
        }
        if (player.Paused && mainCamera != null)
        {
            mainCamera.transform.localPosition = new Vector3(-85.77416f, 32.8305f, -69.88891f);
            mainCamera.transform.localRotation = Quaternion.Euler(16.48679f, 21.83607f, 6.487632f);
            return;
        }

        if (player.networkView.isMine)
        {
            // Update inferred position and velocity
            Vector3 newPosition   = player.transform.position;
            Vector3 newVelocity   = (newPosition - LastInferredBodyPosition) / Time.deltaTime;
            Vector3 velocityDelta = newVelocity - LastInferredVelocity;
            LastInferredVelocity     = newVelocity;
            LastInferredBodyPosition = newPosition;
            AddYSpringImpulse(velocityDelta.y);
            YSpring.Update();
            // Clamp magnitude to prevent camera from clipping through ground on hard landings
            YSpring.CurrentValue = Mathf.Clamp(YSpring.CurrentValue, -4f, 4f);
            if (IsExteriorView)
            {
                BarrelFirstPersonOffsetTransform.localPosition = Vector3.zero;
            }
            else
            {
                // Values between 0.3f and 0.8f seem to look best for scaling the gun offset Y.
                BarrelFirstPersonOffsetTransform.localPosition = new Vector3(0f, YSpring.CurrentValue * 0.3f, 0f);
            }

            ViewBobSpring.Update();

            // Higher delay time when the camera is further from the gun
            QueuedScreenRecoils.DelayTime = IsExteriorView ? 0.071f : 0.048f;
            //QueuedScreenRecoils.DelayTime = 0.06f;
            // Remove stuff from the lag queue and put it in the actual spring
            foreach (var eulerAngles in QueuedScreenRecoils.Update())
            {
                CosmeticSpring.AddImpulse(eulerAngles);
            }
            CosmeticSpring.Update();

            if (Input.GetButtonDown("ToggleCameraSmoothing"))
            {
                HasSmoothedRotation = !HasSmoothedRotation;
            }
            if (Input.GetButtonDown("ToggleRaycastCrosshair"))
            {
                UsesRaycastCrosshair = !UsesRaycastCrosshair;
            }

            // Smooth changes in base field of view (if player adjusts FOV, we
            // want it to be a slower smoothing than zooming in/out)
            SmoothedBaseFieldOfView = Mathf.Lerp(SmoothedBaseFieldOfView, BaseFieldOfView,
                                                 1.0f - Mathf.Pow(0.0001f, Time.deltaTime));
            // Interpolate field of view, set on main camera if necessary
            SmoothedFieldOfView = Mathf.Lerp(SmoothedFieldOfView, DesiredFieldOfView,
                                             1.0f - Mathf.Pow(0.000001f, Time.deltaTime));
            if (mainCamera != null)
            {
                if (!Mathf.Approximately(mainCamera.fieldOfView, SmoothedFieldOfView))
                {
                    mainCamera.fieldOfView = SmoothedFieldOfView;
                }
            }

            // Update and smooth view position
            SmoothedViewOffset = Vector3.Lerp(SmoothedViewOffset, DesiredViewOffset,
                                              1.0f - Mathf.Pow(0.00001f, Time.deltaTime));
            transform.localPosition = SmoothedViewOffset;

            // TODO we need smarter handling for toggilng smoothing and first/third person at the same time
            if (HasSmoothedRotation && IsExteriorView)
            {
                // TODO make a nicer interface for goofy power curve
                var amt = (float)Math.Pow(0.0000000000001, Time.deltaTime);
                actualCameraRotation = Quaternion.Slerp(actualCameraRotation, transform.rotation, 1.0f - amt);
            }
            else
            {
                actualCameraRotation = transform.rotation;
            }

            Vector3 scaledLocalPosition = Vector3.Scale(transform.localPosition, transform.lossyScale);
            Vector3 direction           = actualCameraRotation * scaledLocalPosition;
            Vector3 cameraPosition      = transform.parent.position + direction;

            // Modify Y for spring
            cameraPosition.y += YSpring.CurrentValue;

            // We don't want to use view bob when zoomed in: we want the
            // reticule to be very responsive.
            Quaternion usedViewBob = Quaternion.Lerp(
                ViewBobSpring.CurrentValue, Quaternion.identity, ZoomedAmount);

            // TODO can mainCamera be null here?
            if (mainCamera != null)
            {
                mainCamera.transform.position = cameraPosition;
                mainCamera.transform.rotation =
                    actualCameraRotation *
                    usedViewBob *
                    CosmeticSpring.CurrentValue;
            }


            var rawCrosshairPosition = GetCrosshairPosition();
            SmoothedCrosshairPosition = Vector2.Lerp(SmoothedCrosshairPosition, rawCrosshairPosition,
                                                     1.0f - Mathf.Pow(CrosshairSmoothingSpeed, -CrosshairSmoothingSpeed * Time.deltaTime));
            Camera.main.GetComponent <WeaponIndicatorScript>()
            .CrosshairPosition = SmoothedCrosshairPosition;
        }
    }